iPhoneのサンプルプログラム その2

SATCHを用いたナビアプリ(2)

disp1.lua(SATCHのスクリプト)
local componentInterface = getComponentInterface()
local scene = getCurrentScene()
local tRoll = Text2D(scene:getObjectByName("txtRoll"))
local tPitch = Text2D(scene:getObjectByName("txtPitch"))
local tYaw = Text2D(scene:getObjectByName("txtYaw"))

local isCommand = nil
local command = nil

repeat

	if componentInterface then
		isCommand, command = componentInterface:pullCommand()
		if isCommand then
			if command["CommandName"]=="sendGyro" then				
				tRoll:setText("Roll:"..command["arg0"])
				tPitch:setText("Pitch:"..command["arg1"])
				tYaw:setText("Yaw:"..command["arg2"])
			end
		end
	end

until coroutine.yield()

AppDelegate.h
#import <Foundation/Foundation.h>
#import <CoreMotion/CoreMotion.h>
#import "satchARViewer.h"

@interface AppDelegate : NSObject <UIApplicationDelegate>
{
    UIWindow *window;
    UIView *mRender;
    SatchARViewer *mPlayer;
    
    CMMotionManager *motionManager;
    CMAttitude *referenceAttitude;
    BOOL isCaptured;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UIView *mRender;

- (void)start;
- (void)stop;

@end

AppDelegeta.mm
#import "AppDelegate.h"

@implementation AppDelegate

@synthesize window;
@synthesize mRender;

- (void)dealloc
{
    [self stop];
	
    if (mPlayer) {
        [mPlayer terminate];
        [mPlayer release];
        mPlayer = nil;
    }
	
    [motionManager release];
    [mRender release];
    [window release];
    [super dealloc];
}

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [SatchARViewer setDialogMessageLoading:@"ロ−ディング..."];
    [SatchARViewer
     setToastMessageNoNetworkConnection:@"ネットワークに接続されていません。"];
    [SatchARViewer setToastMessageNetworkError:@"通信中にエラーが発生しました。"];
    [SatchARViewer setToastMessageLicenceError:@"認証に失敗しました。"];
    
    mRender = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
    [window addSubview:mRender];
	
    mPlayer = [[[SatchARViewer alloc] init] initialize:mRender];
    [self.window makeKeyAndVisible];
    [self start];
    
    motionManager = [[CMMotionManager alloc] init];
    motionManager.deviceMotionUpdateInterval = 1.0f/4.0f; // ジャイロのサンプリング間隔[s]    
    isCaptured = NO;
    referenceAttitude = nil;
    [self startGyro];

    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    if (mPlayer != nil) {
        [mPlayer applicationWillResignActive];
    }
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    if (mPlayer != nil) {
        [mPlayer applicationDidEnterBackground];
    }
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    if (mPlayer != nil) {
        [mPlayer applicationWillEnterForeground];
    }
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    if (mPlayer != nil) {
        [mPlayer applicationDidBecomeActive];
    }
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    if (mPlayer != nil) {
        [mPlayer applicationWillTerminate];
    }
}

- (void)callback:(NSNumber*)num
{
    switch ([num intValue]) {
        case LOAD_SCENARIO_STATUS_COMPLETE:
            [mPlayer playScenario];
            break;
    }
}

- (void)start
{
    if (mPlayer) {
        [mPlayer loadScenario:@"Gyro0_iphone/Gyro0.dpd"
                     callback:@selector(callback:)
                          obj:self];
    }
}

- (void)stop
{
    if (mPlayer && ![mPlayer isScenarioPaused]) {
        [mPlayer pauseScenario];
    }
}

- (void)startGyro
{
    // デバイスのハードウェアチェック
    if (!motionManager.deviceMotionAvailable)
    {
        NSLog(@"DeviceMotion is not available.");
        return;
    }
    
    isCaptured = NO;
    
    // モーションデータ更新時のハンドラを作成
    void (^handler)(CMDeviceMotion *, NSError *) = ^(CMDeviceMotion *motion, NSError *error)
    {
        if (isCaptured == NO) {
            referenceAttitude = [motion.attitude retain];
            isCaptured = YES;
        }
        else {
            // ジャイロデータの記録
            [self recordGyroData:motion];
        }
    };
    
    // モーションデータの測定を開始
    NSOperationQueue *queue = [NSOperationQueue currentQueue];
    [motionManager startDeviceMotionUpdatesToQueue:queue withHandler:handler];
}

- (void)recordGyroData:(CMDeviceMotion *)motion
{
    if (!mPlayer) {
        return;
    }
    
    CMAttitude *currentAttitude = motion.attitude;
    
    if (referenceAttitude != nil) {
        [currentAttitude multiplyByInverseOfAttitude: referenceAttitude];
    }
    
    // 角度を度数に変換
    float rollDegree = 180 * currentAttitude.roll / M_PI;
    float pitchDegree = 180 * currentAttitude.pitch / M_PI;
    float yawDegree = 180 * currentAttitude.yaw / M_PI;

    NSString *_roll = [NSString stringWithFormat:@"%.4f", rollDegree];
    NSString *_pitch = [NSString stringWithFormat:@"%.4f", pitchDegree];
    NSString *_yaw = [NSString stringWithFormat:@"%.4f", yawDegree];
    
    NSArray *para = [NSArray arrayWithObjects:_roll, _pitch, _yaw, nil];
//    NSLog(@"roll=%f, pitch=%f, yaw=%f", rollDegree, pitchDegree, yawDegree);

    [mPlayer enqueueCommand:@"sendGyro" args:para];
}

@end