Changeset 9015b1e in orbit
- Timestamp:
- 07/19/13 15:59:47 (9 years ago)
- Branches:
- master, RawEEG, Servo, Tab_Interface, pyramid
- Children:
- ce0a7ee, c61115c
- Parents:
- ab9d63b
- Location:
- iOS/Orbit
- Files:
-
- 1 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
iOS/Orbit/Orbit/AppDelegate.m
rab9d63b r9015b1e 21 21 { 22 22 // Override point for customization after application launch. 23 NSLog(@"didFinsihLaunching - signal convertor init"); 23 24 signalConverter = [[SignalConverter alloc] init]; 24 25 // [[TGAccessoryManager sharedTGAccessoryManager] setupManagerWithInterval:0.05]; … … 33 34 // ViewController *rootController = (ViewController *)self.window.rootViewController; 34 35 // [rootController appClosed]; 36 [signalConverter appStopped]; 37 NSLog(@"Application will resign active - appClosed"); 35 38 } 36 39 … … 49 52 { 50 53 // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 51 // ViewController *rootController = (ViewController *)self.window.rootViewController;52 // [rootController appForegrounded];53 54 } 54 55 … … 56 57 { 57 58 // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 59 NSLog(@"Application will terminate - teardownManager"); 58 60 [[TGAccessoryManager sharedTGAccessoryManager] teardownManager]; 59 61 } -
iOS/Orbit/Orbit/SignalConverter.h
rab9d63b r9015b1e 25 25 - (void) setValuesForAttention:(float) attention meditation:(float) meditation; 26 26 - (void) prepare; 27 - ( void) startProcessing;27 - (BOOL) startProcessing; 28 28 - (void) stopProcessing; 29 - (void) appClosed; 29 - (void) appStopped; 30 - (BOOL) isBluetoothReady; 31 - (BOOL) isVolumeMax; 30 32 31 33 @end -
iOS/Orbit/Orbit/SignalConverter.m
rab9d63b r9015b1e 13 13 #define ATTENTION_KEY @"eSenseAttention" 14 14 #define MEDITATION_KEY @"eSenseMeditation" 15 16 #define CHANNEL_A 1 15 17 16 18 // Converts signals received from the EEG headset to the audio played to fly the helicopter. … … 29 31 @synthesize attentionThreshold, meditationThreshold, running; 30 32 33 34 - (id) init 35 { 36 self = [super init]; 37 if (self) 38 { 39 [[TGAccessoryManager sharedTGAccessoryManager] setupManagerWithInterval:0.05]; 40 [[TGAccessoryManager sharedTGAccessoryManager] setDelegate:self]; 41 } 42 return self; 43 } 44 31 45 - (void) setValuesForAttention:(float) attention meditation:(float) meditation 32 46 { … … 45 59 } 46 60 47 - (void) appClosed 48 { 49 if ([[TGAccessoryManager sharedTGAccessoryManager] connected]) { 61 - (void) appStopped 62 { 63 running = NO; 64 if ([TGAccessoryManager sharedTGAccessoryManager].accessory != nil) { 50 65 [[TGAccessoryManager sharedTGAccessoryManager] stopStream]; 66 } 67 [audioPlayer stop]; 68 if (_delegate != nil) { 69 [_delegate appStopped]; 51 70 } 52 71 } … … 105 124 // The headset was switched on, start the data stream 106 125 - (void)accessoryDidConnect:(EAAccessory *)accessory { 107 if (_delegate != nil)108 {109 [_delegate notifyHeadsetConnect];110 }111 if ([[TGAccessoryManager sharedTGAccessoryManager] accessory] != nil) {112 [[TGAccessoryManager sharedTGAccessoryManager] startStream];113 }114 126 } 115 127 … … 122 134 } 123 135 136 - (BOOL) isBluetoothReady 137 { 138 return [[TGAccessoryManager sharedTGAccessoryManager] accessory] != NULL; 139 } 140 141 - (BOOL) isVolumeMax 142 { 143 float volume = [[AVAudioSession sharedInstance] outputVolume]; 144 // Float32 volume; 145 // UInt32 dataSize = sizeof(Float32); 146 // 147 // AudioSessionGetProperty ( 148 // kAudioSessionProperty_CurrentHardwareOutputVolume, 149 // &dataSize, 150 // &volume 151 // ); 152 return volume == 1.0; 153 } 154 124 155 #pragma mark start / stop methods 125 156 126 - (void) startProcessing 127 { 128 running = YES; 157 - (BOOL) startProcessing 158 { 129 159 EAAccessory *accessory = [[TGAccessoryManager sharedTGAccessoryManager] accessory]; 130 160 if (accessory != nil) { 131 if (_delegate != nil)132 {161 running = YES; 162 if (_delegate != nil) { 133 163 [_delegate notifyDeviceConnected: accessory.name]; 134 164 } 135 165 [[TGAccessoryManager sharedTGAccessoryManager] startStream]; 136 166 } 167 return running; 137 168 } 138 169 139 170 - (void) stopProcessing 140 171 { 141 running = NO; 142 if ([[TGAccessoryManager sharedTGAccessoryManager] connected]) { 143 [[TGAccessoryManager sharedTGAccessoryManager] stopStream]; 144 } 145 [audioPlayer stop]; 172 [self appStopped]; 146 173 [self prepare]; 147 174 } … … 202 229 } 203 230 231 // calculate the checksum for the generated code used to generate the WAV array 232 - (int) codeChecksum:(int)code 233 { 234 int checksum = 0; 235 for (int i = 0; i < 7; i++) { 236 checksum += (code >> 4*i) & 15; 237 } 238 return 16 - (checksum & 15); 239 } 240 241 // Generate the code used to create the WAV file based on the given throttle, yaw and pitch. 242 // Copied from AudioService.java in the Android app 243 // throttle: 0~127, nothing will happen if this value is below 30. 244 // yaw: 0~127, normally 78 will keep orbit from rotating. 245 // pitch: 0~63, normally 31 will stop the top propeller. 246 // channel: 1=Channel A, 0=Channel B 2= Channel C, depend on which channel you want to pair to the orbit. You can fly at most 3 orbit in a same room. 247 - (int) generateCodeFromThrottle: (int)throttle yaw: (int)yaw pitch: (int)pitch channel: (int)channel 248 { 249 int code = (throttle << 21) + 1048576 + (yaw << 12) + (pitch << 4) + (((channel >> 1) & 1) << 19) + ((channel & 1) << 11); 250 return code;// + codeChecksum(code); 251 } 252 204 253 @end -
iOS/Orbit/Orbit/SignalConverterDelegate.h
rab9d63b r9015b1e 19 19 - (void) notifyHeadsetDisconnect; 20 20 - (void) notifyDeviceConnected:(NSString *)name; 21 - (void) appStopped; 21 22 @end -
iOS/Orbit/Orbit/controllers/FlightViewController.m
rab9d63b r9015b1e 23 23 @implementation FlightViewController { 24 24 SignalConverter *signalConverter; 25 int deviceStatus; 25 26 } 26 27 27 @synthesize status, attention, meditation, signal, power, attentionThreshold, meditationThreshold, connectButton, statusImage ;28 @synthesize status, attention, meditation, signal, power, attentionThreshold, meditationThreshold, connectButton, statusImage, signalPercent, attentionPercent, meditationPercent, powerPercent; 28 29 29 30 - (void)viewDidLoad … … 39 40 } 40 41 41 // Start the data stream from the bluetooth headset if it's attached, and reset the display output42 - (void) appForegrounded43 {44 [self resetViews]; // just in case it didn't happen on close45 }46 47 42 #pragma mark view updates 48 43 … … 51 46 { 52 47 signal.progress = 0; 48 signalPercent.text = @"0%"; 53 49 attention.progress = 0; 50 attentionPercent.text = @"0%"; 54 51 meditation.progress = 0; 52 meditationPercent.text = @"0%"; 55 53 power.progress = 0; 54 powerPercent.text = @"0%"; 56 55 [self logMessage:@"Disconnected"]; 56 [self updateStatusImage:STATUS_DEFAULT]; 57 connectButton.title = @"Connect"; 57 58 } 58 59 59 60 - (void) updateStatusImage:(int) statusNo 60 61 { 61 [statusImage setImage: [UIImage imageNamed:[NSString stringWithFormat:@"status_%u", statusNo]]]; 62 if (statusNo != deviceStatus) { 63 [statusImage setImage: [UIImage imageNamed:[NSString stringWithFormat:@"status_%u", statusNo]]]; 64 deviceStatus = statusNo; 65 if (statusNo == STATUS_CONNECTED) { 66 [self logMessage:@"Check headset fitted properly"]; 67 } else if (statusNo == STATUS_PROCESSING) { 68 [self logMessage:@"Increase your concentration"]; 69 } else if (statusNo == STATUS_ACTIVE) { 70 [self logMessage:@"Flying!"]; 71 } 72 } 62 73 } 63 74 … … 65 76 { 66 77 [signalConverter setValuesForAttention:attentionThreshold.value meditation:meditationThreshold.value]; 67 //68 // if (attentionThreshold.value < 0.2) {69 // [self updateStatusImage:STATUS_DEFAULT];70 // } else if (attentionThreshold.value < 0.4) {71 // [self updateStatusImage:STATUS_CONNECTING];72 // } else if (attentionThreshold.value < 0.6) {73 // [self updateStatusImage:STATUS_CONNECTED];74 // } else if (attentionThreshold.value < 0.8) {75 // [self updateStatusImage:STATUS_PROCESSING];76 // } else {77 // [self updateStatusImage:STATUS_ACTIVE];78 // }79 78 } 80 79 … … 99 98 self.power.progress = powerLevel; 100 99 self.powerPercent.text = [NSString stringWithFormat:@"%i%%", (int)(powerLevel * 100)]; 100 [self updateStatusImage:[self statusFromSignal:signalStrength power:powerLevel]]; 101 } 102 103 - (int) statusFromSignal: (float)signalLevel power:(float)powerLevel 104 { 105 if (signalLevel < 0.9) { // weak signal 106 return STATUS_CONNECTED; 107 } else if (powerLevel == 0.0) { // strong signal but thresholds not met 108 return STATUS_PROCESSING; 109 } else { // flight command sent to orbit 110 return STATUS_ACTIVE; 111 } 101 112 } 102 113 103 114 - (void) notifyHeadsetConnect 104 115 { 105 [self logMessage:@"Headet connected"]; 116 [self logMessage:@"Headset connected"]; 117 [self updateStatusImage:STATUS_CONNECTING]; 106 118 } 107 119 … … 110 122 // Reset the outputs back to zero 111 123 [self resetViews]; 112 [self logMessage:@"Headet disconnected"];113 124 } 114 125 115 126 - (void) notifyDeviceConnected:(NSString *)name 116 127 { 117 [self logMessage:[NSString stringWithFormat:@"EEG device %@ connected", name]]; 128 [self logMessage:[NSString stringWithFormat:@"EEG device %@ connected", name]]; 129 [self updateStatusImage:STATUS_CONNECTING]; 130 connectButton.title = @"Disconnect"; 131 } 132 133 - (void) appStopped 134 { 135 [self resetViews]; // just in case it didn't happen on close 118 136 } 119 137 … … 124 142 if (signalConverter.running) { 125 143 [signalConverter stopProcessing]; 126 connectButton.title = @"Connect";127 144 [self resetViews]; 145 } else if (!signalConverter.isBluetoothReady) { 146 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Device not found" message:@"No Bluetooth device detected. Ensure Bluetooth is on and the Mindwave headset is paired" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; 147 [alert show]; 148 } else if (!signalConverter.isVolumeMax) { 149 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Turn Up The Volume" message:@"Your device volume must be at the maximum for proper operation" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; 150 [alert show]; 151 } else if ([signalConverter startProcessing]) { 152 [self logMessage:@"Searching for device"]; 153 // [self updateStatusImage:STATUS_CONNECTING]; 154 connectButton.title = @"Disconnect"; 128 155 } else { 129 [self logMessage:@"Searching for device"]; 130 [signalConverter startProcessing]; 131 connectButton.title = @"Disconnect"; 156 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Failed to connect" message:@"Check the device is correctly paired on Bluetooth" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; 157 [alert show]; 132 158 } 133 159 } -
iOS/Orbit/Orbit/en.lproj/MainStoryboard.storyboard
rab9d63b r9015b1e 385 385 <navigationItem key="navigationItem" id="iTN-dz-EXc"/> 386 386 <connections> 387 <outlet property="attention" destination="Dly-NW-R1i" id="XDF-jJ-Fgu"/> 387 388 <outlet property="attentionPercent" destination="bZn-rG-svm" id="1Ap-Cq-hIM"/> 388 389 <outlet property="attentionThreshold" destination="ym8-zN-dSb" id="baB-wY-lJS"/> 389 390 <outlet property="connectButton" destination="Lwp-ZU-iKO" id="zdp-si-XhL"/> 391 <outlet property="meditation" destination="tsc-gq-wnT" id="y0Z-Xa-LgD"/> 390 392 <outlet property="meditationPercent" destination="Rhw-9S-ZP1" id="Wws-f9-lVM"/> 391 393 <outlet property="meditationThreshold" destination="LJj-vt-JUw" id="UKy-Vg-8gL"/> 394 <outlet property="power" destination="KeR-cO-90u" id="wwM-U5-g6n"/> 392 395 <outlet property="powerPercent" destination="ah9-c0-kCb" id="IF6-xV-7Xf"/> 396 <outlet property="signal" destination="AuD-cU-2pt" id="uuu-hc-E2e"/> 393 397 <outlet property="signalPercent" destination="yYn-76-IoI" id="4Ei-JM-jZ1"/> 394 398 <outlet property="status" destination="BOS-Js-1rx" id="fDM-Of-lza"/> -
iOS/Orbit/orbit.xcodeproj/project.pbxproj
rab9d63b r9015b1e 38 38 28C10EEC16875BC100ECFD59 /* throttle_hover_ios.wav in Resources */ = {isa = PBXBuildFile; fileRef = 28C10EEB16875BC100ECFD59 /* throttle_hover_ios.wav */; }; 39 39 28C10EF1168760CA00ECFD59 /* HOW_TO_USE.txt in Resources */ = {isa = PBXBuildFile; fileRef = 28C10EF0168760CA00ECFD59 /* HOW_TO_USE.txt */; }; 40 28F901301799436F003FB5ED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28F9012F1799436F003FB5ED /* CoreBluetooth.framework */; }; 40 41 52922BA817004D1400A39146 /* libCorePlot-CocoaTouch.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 52922BA717004D1400A39146 /* libCorePlot-CocoaTouch.a */; }; 41 42 52FA364416899B5D004C280A /* ic_launcher-57x57.png in Resources */ = {isa = PBXBuildFile; fileRef = 52FA364316899B5D004C280A /* ic_launcher-57x57.png */; }; … … 88 89 28C10EEB16875BC100ECFD59 /* throttle_hover_ios.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = throttle_hover_ios.wav; sourceTree = "<group>"; }; 89 90 28C10EF0168760CA00ECFD59 /* HOW_TO_USE.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = HOW_TO_USE.txt; sourceTree = "<group>"; }; 91 28F9012F1799436F003FB5ED /* CoreBluetooth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreBluetooth.framework; path = System/Library/Frameworks/CoreBluetooth.framework; sourceTree = SDKROOT; }; 90 92 52922BA717004D1400A39146 /* libCorePlot-CocoaTouch.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libCorePlot-CocoaTouch.a"; sourceTree = "<group>"; }; 91 93 52922BA917004D4400A39146 /* CorePlot-CocoaTouch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CorePlot-CocoaTouch.h"; sourceTree = "<group>"; }; … … 174 176 buildActionMask = 2147483647; 175 177 files = ( 178 28F901301799436F003FB5ED /* CoreBluetooth.framework in Frameworks */, 176 179 52922BA817004D1400A39146 /* libCorePlot-CocoaTouch.a in Frameworks */, 177 180 2815BC15167F496C00F7E6DA /* QuartzCore.framework in Frameworks */, … … 205 208 isa = PBXGroup; 206 209 children = ( 210 28F9012F1799436F003FB5ED /* CoreBluetooth.framework */, 207 211 289C7D0F178D7A21005C08EC /* Images */, 208 212 52FA364716899C63004C280A /* Default-568h@2x.png */,
Note: See TracChangeset
for help on using the changeset viewer.