How to access motion & orientation information of remote?

From the presentation it seemed the AppleTV remote has some hardware that detects motion and orientation. IIRC even a tennis like game was demo-ed.


How would I access this information of the remote for my own apps and / or games? I can't seem to find any documentation on this. Seems the GCController classes don't apply to the remote and the CoreMotion framework isn't available either.

Accepted Reply

Well, I finally figured it all out.


First of all, one needs to use NSNotificationCenter to find the controllers. Probably best to do this when app launches. Something like this:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controllerDidConnect:) name:GCControllerDidConnectNotification object:nil];


We can then use the following code after connecting to store the device info in a property:


- (void)controllerDidConnect:(NSNotification *)notification {
    self.myController = notification.object;
}

The remote profile is a subclass of the micro gamepad profile. Motion and other data can be tracked by adding a value changed event handler:

  GCMicroGamepad *profile =  self.myController.microGamepad
  profile.valueChangedHandler= ^ (GCMicroGamepad *gamepad, GCControllerElement *element) {
        if (self.myController.motion) {
            NSLog(@"motion supported");
            NSLog(@"gravity: %f %f %f", self.myController.motion.gravity.x, self.myController.motion.gravity.y, self.myController.motion.gravity.z);
            NSLog(@"userAcc: %f %f %f", self.myController.motion.userAcceleration.x, self.myController.motion.userAcceleration.y, self.myController.motion.userAcceleration.z);
            NSLog(@"rotationRate: %f %f %f", self.myController.motion.rotationRate.x, self.myController.motion.rotationRate.y, self.myController.motion.rotationRate.z);
            NSLog(@"attitude: %f %f %f %f", self.myController.motion.attitude.x, self.myController.motion.attitude.y, self.myController.motion.attitude.z, self.myController.motion.attitude.w);
        }
    };

Replies

Well, I finally figured it all out.


First of all, one needs to use NSNotificationCenter to find the controllers. Probably best to do this when app launches. Something like this:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controllerDidConnect:) name:GCControllerDidConnectNotification object:nil];


We can then use the following code after connecting to store the device info in a property:


- (void)controllerDidConnect:(NSNotification *)notification {
    self.myController = notification.object;
}

The remote profile is a subclass of the micro gamepad profile. Motion and other data can be tracked by adding a value changed event handler:

  GCMicroGamepad *profile =  self.myController.microGamepad
  profile.valueChangedHandler= ^ (GCMicroGamepad *gamepad, GCControllerElement *element) {
        if (self.myController.motion) {
            NSLog(@"motion supported");
            NSLog(@"gravity: %f %f %f", self.myController.motion.gravity.x, self.myController.motion.gravity.y, self.myController.motion.gravity.z);
            NSLog(@"userAcc: %f %f %f", self.myController.motion.userAcceleration.x, self.myController.motion.userAcceleration.y, self.myController.motion.userAcceleration.z);
            NSLog(@"rotationRate: %f %f %f", self.myController.motion.rotationRate.x, self.myController.motion.rotationRate.y, self.myController.motion.rotationRate.z);
            NSLog(@"attitude: %f %f %f %f", self.myController.motion.attitude.x, self.myController.motion.attitude.y, self.myController.motion.attitude.z, self.myController.motion.attitude.w);
        }
    };

Very clear code, thank you, but be aware that the rotationRate and attitude are NOT useful (always returning 0,0,0 and 0,0,0,1 respectively, see the documentation in the headers).


Something related to these values can of course be calculated from the gravity and userAcceleration (the orientation of the device can be derived from the gravity vector and the rotationRate can be estimated from the changes in gravity over time).

Is there a swift version of this? Trying to move away from Object-C in my code.

Gravity and user acceleration are calculated from accelerometer raw data.

Attitude and rotation rate from gyro raw data. Why they are always fixed values? Is gyro working atm?

Is there a way to read raw data from a remote?

Can we try this on simulator?