2 // MainViewController.m
5 // Created by Mykonos on 17/12/09.
6 // Copyright 2009 Parrot SA. All rights reserved.
8 #import "MainViewController.h"
9 #import "OpenGLVideo.h"
11 extern navdata_unpacked_t ctrlnavdata;
13 @interface MainViewController ()
14 ARDroneNavigationData navigationData;
15 ARDroneEnemiesData humanEnemiesData;
16 ARDroneDetectionCamera detectionCamera;
17 ARDroneCamera droneCamera;
19 id<NavdataProtocol>navdata_delegate;
21 BOOL screenOrientationRight;
23 ARDroneHUDConfiguration hudconfig;
24 ControlData *controlData;
30 @implementation MainViewController
31 - (id) initWithFrame:(CGRect)frame withState:(BOOL)inGame withDelegate:(id<ARDroneProtocolOut>)delegate withNavdataDelegate:(id<NavdataProtocol>)_navdata_delegate withControlData:(ControlData*)_controlData withHUDConfiguration:(ARDroneHUDConfiguration*)hudconfiguration
33 NSLog(@"Main View Controller Frame : %@", NSStringFromCGRect(frame));
34 if(self = [super init])
37 screenOrientationRight = YES;
39 gameEngine = delegate;
40 navdata_delegate = _navdata_delegate;
41 controlData = _controlData;
43 vp_os_memset(&navigationData, 0x0, sizeof(ARDroneNavigationData));
44 vp_os_memset(&detectionCamera, 0x0, sizeof(ARDroneCamera));
45 vp_os_memset(&droneCamera, 0x0, sizeof(ARDroneCamera));
46 humanEnemiesData.count = 0;
48 for(int i = 0 ; i < ARDRONE_MAX_ENEMIES ; i++)
50 vp_os_memset(&humanEnemiesData.data[i], 0x0, sizeof(ARDroneEnemyData));
51 humanEnemiesData.data[i].width = 1.0;
52 humanEnemiesData.data[i].height = 1.0;
55 if(hudconfiguration == nil)
57 hudconfig.enableBackToMainMenu = NO;
58 hudconfig.enableSwitchScreen = YES;
59 hudconfig.enableBatteryPercentage = YES;
63 vp_os_memcpy(&hudconfig, hudconfiguration, sizeof(ARDroneHUDConfiguration));
66 hud = [[HUD alloc] initWithFrame:screenFrame withState:inGame withHUDConfiguration:hudconfig withControlData:controlData];
67 [self.view addSubview:hud.view];
68 hud.view.multipleTouchEnabled = YES;
70 menuSettings = [[SettingsMenu alloc] initWithFrame:screenFrame AndHUDConfiguration:hudconfig withDelegate:hud withControlData:controlData];
71 menuSettings.view.hidden = YES;
72 menuSettings.view.multipleTouchEnabled = YES;
73 [self.view addSubview:menuSettings.view];
74 self.view.multipleTouchEnabled = YES;
76 [self changeState:inGame];
78 [NSThread detachNewThreadSelector:@selector(TimerHandler) toTarget:self withObject:nil];
84 - (void)setWifiReachabled:(BOOL)reachabled
86 controlData->wifiReachabled = reachabled;
89 -(void)setScreenOrientationRight:(BOOL)right
91 screenOrientationRight = right;
96 static CONFIG_STATE prev_config_state = CONFIG_STATE_IDLE;
97 static bool_t prev_navdata_connected = FALSE;
99 if(prev_config_state != controlData->configurationState)
101 if(controlData->configurationState == CONFIG_STATE_IDLE)
102 [menuSettings configChanged];
103 prev_config_state = controlData->configurationState;
106 if(prev_navdata_connected != controlData->navdata_connected)
108 [menuSettings configChanged];
109 prev_navdata_connected = controlData->navdata_connected;
112 if(hud.firePressed == YES)
114 [gameEngine executeCommandOut:ARDRONE_COMMAND_FIRE withParameter:nil fromSender:self.view];
116 else if(hud.mainMenuPressed == YES)
118 hud.mainMenuPressed = NO;
119 [gameEngine executeCommandOut:ARDRONE_COMMAND_PAUSE withParameter:nil fromSender:self.view];
121 else if(hud.settingsPressed == YES)
123 hud.settingsPressed = NO;
124 [menuSettings performSelectorOnMainThread:@selector(switchDisplay) withObject:nil waitUntilDone:YES];
128 navigationData.linearVelocity.x = -ctrlnavdata.navdata_demo.vy;
129 navigationData.linearVelocity.y = ctrlnavdata.navdata_demo.vz;
130 navigationData.linearVelocity.z = ctrlnavdata.navdata_demo.vx;
131 navigationData.angularPosition.x = -ctrlnavdata.navdata_demo.theta / 1000;
132 navigationData.angularPosition.y = ctrlnavdata.navdata_demo.psi / 1000;
133 navigationData.angularPosition.z = ctrlnavdata.navdata_demo.phi / 1000;
134 navigationData.navVideoNumFrames = ctrlnavdata.navdata_demo.num_frames;
135 navigationData.videoNumFrames = get_video_current_numframes();
138 ARDRONE_FLYING_STATE tmp_state = ardrone_navdata_get_flying_state(ctrlnavdata);
139 if(navigationData.flyingState != tmp_state)
141 NSLog(@"Flying state switch to %d", tmp_state);
142 if(hudconfig.enableBackToMainMenu)
143 [hud showBackToMainMenu:(tmp_state == ARDRONE_FLYING_STATE_LANDED)];
146 navigationData.flyingState = tmp_state;
147 navigationData.emergencyState = ctrlnavdata.ardrone_state & ARDRONE_EMERGENCY_MASK;
148 navigationData.detection_type = (ARDRONE_CAMERA_DETECTION_TYPE)ctrlnavdata.navdata_demo.detection_camera_type;
149 navigationData.finishLineCount = ctrlnavdata.navdata_games.finish_line_counter;
150 navigationData.doubleTapCount = ctrlnavdata.navdata_games.double_tap_counter;
151 navigationData.isInit = (ctrlnavdata.ardrone_state & ARDRONE_NAVDATA_BOOTSTRAP) ? 0 : 1;
153 // Set detected ARDRONE_ENEMY_HUMAN enemies if detected.
154 humanEnemiesData.count = MIN(ctrlnavdata.navdata_vision_detect.nb_detected, ARDRONE_MAX_ENEMIES);
156 //printf("enemies count : %d\n", humanEnemiesData.count);
157 for(int i = 0 ; i < humanEnemiesData.count ; i++)
159 humanEnemiesData.data[i].width = 2 * ctrlnavdata.navdata_vision_detect.width[i] / 1000.0;
160 humanEnemiesData.data[i].height = 2 * ctrlnavdata.navdata_vision_detect.height[i] / 1000.0;
161 humanEnemiesData.data[i].position.x = (2 * ctrlnavdata.navdata_vision_detect.xc[i] / 1000.0) - 1.0;
162 humanEnemiesData.data[i].position.y = -(2 * ctrlnavdata.navdata_vision_detect.yc[i] / 1000.0) + 1.0;
163 humanEnemiesData.data[i].position.z = ctrlnavdata.navdata_vision_detect.dist[i];
164 humanEnemiesData.data[i].orientation_angle = ctrlnavdata.navdata_vision_detect.orientation_angle[i];
167 // Set Detection Camera
168 vp_os_memcpy(detectionCamera.rotation, &ctrlnavdata.navdata_demo.detection_camera_rot, sizeof(float) * 9);
169 vp_os_memcpy(detectionCamera.translation, &ctrlnavdata.navdata_demo.detection_camera_trans, sizeof(float) * 3);
170 detectionCamera.tag_index = ctrlnavdata.navdata_demo.detection_tag_index;
172 // Set Drone Camera rotation
173 vp_os_memcpy(droneCamera.rotation, &ctrlnavdata.navdata_demo.drone_camera_rot, sizeof(float) * 9);
175 // Set Drone Camera translation
177 if ([gameEngine respondsToSelector:@selector(AIEnemiesData:)])
179 ARDroneEnemiesData AIEnemiesData;
180 vp_os_memset(&AIEnemiesData, 0x0, sizeof(ARDroneEnemiesData));
181 [gameEngine AIEnemiesData:&AIEnemiesData];
184 vp_os_memcpy(&droneCamera.translation[0], &ctrlnavdata.navdata_demo.drone_camera_trans, sizeof(float) * 3);
186 // Set battery level in hud view
187 [hud setBattery:(int)ctrlnavdata.navdata_demo.vbat_flying_percentage];
189 // Set all texts in Hud view
190 if((strlen(controlData->error_msg) != 0) && (controlData->framecounter >= (kFPS / 2.0)))
191 [hud setMessageBox:[[NSBundle mainBundle] localizedStringForKey :[NSString stringWithCString:controlData->error_msg encoding:NSUTF8StringEncoding] value:@"" table:@"languages"]];
193 [hud setMessageBox:@""];
195 [hud performSelectorOnMainThread:@selector(setTakeOff:) withObject:[NSString stringWithFormat:@"%s", controlData->takeoff_msg] waitUntilDone:YES];
196 [hud performSelectorOnMainThread:@selector(setEmergency:) withObject:[NSString stringWithFormat:@"%s", controlData->emergency_msg] waitUntilDone:YES];
199 - (void) TimerHandler {
200 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Top-level pool
202 ardrone_timer_t timer;
203 int refreshTimeInUs = 1000000 / kFPS;
205 ardrone_timer_reset(&timer);
206 ardrone_timer_update(&timer);
210 int delta = ardrone_timer_delta_us(&timer);
211 if( delta >= refreshTimeInUs)
214 ardrone_timer_update(&timer);
216 if(self.view.hidden == NO)
218 [navdata_delegate parrotNavdata:&ctrlnavdata];
219 [self performSelectorOnMainThread:@selector(update) withObject:nil waitUntilDone:YES];
223 controlData->framecounter = (controlData->framecounter + 1) % kFPS;
227 //printf("Time waited : %d us\n", refreshTimeInUs - delta);
228 usleep(refreshTimeInUs - delta);
232 [pool release]; // Release the objects in the pool.
235 - (ARDroneNavigationData*)navigationData
237 return &navigationData;
240 - (ARDroneDetectionCamera*)detectionCamera
242 return &detectionCamera;
245 - (ARDroneCamera*)droneCamera
250 - (ARDroneEnemiesData*)humanEnemiesData
252 return &humanEnemiesData;
255 - (void)changeState:(BOOL)inGame
257 self.view.hidden = !inGame;
258 [hud changeState:inGame];
264 - (void)executeCommandIn:(ARDRONE_COMMAND_IN_WITH_PARAM)commandIn fromSender:(id)sender refreshSettings:(BOOL)refresh
267 switch (commandIn.command) {
269 case ARDRONE_COMMAND_ISCLIENT:
270 i_value = ((int)commandIn.parameter == 0) ? ADC_CMD_SELECT_ULTRASOUND_25Hz : ADC_CMD_SELECT_ULTRASOUND_22Hz;
271 ARDRONE_TOOL_CONFIGURATION_ADDEVENT(ultrasound_freq, &i_value, commandIn.callback);
274 case ARDRONE_COMMAND_DRONE_ANIM:
276 ARDRONE_ANIMATION_PARAM *param = (ARDRONE_ANIMATION_PARAM*)commandIn.parameter;
277 char str_param[SMALL_STRING_SIZE];
278 sprintf(str_param, "%d,%d", param->drone_anim, ((param->timeout == 0) ? MAYDAY_TIMEOUT[param->drone_anim] : param->timeout));
279 ARDRONE_TOOL_CONFIGURATION_ADDEVENT(flight_anim, str_param, commandIn.callback);
283 case ARDRONE_COMMAND_DRONE_LED_ANIM:
285 char param[SMALL_STRING_SIZE];
287 freq.f = ((ARDRONE_LED_ANIMATION_PARAM*)commandIn.parameter)->frequency;
288 sprintf(param, "%d,%d,%d", ((ARDRONE_LED_ANIMATION_PARAM*)commandIn.parameter)->led_anim, freq.i, ((ARDRONE_LED_ANIMATION_PARAM*)commandIn.parameter)->duration);
289 ARDRONE_TOOL_CONFIGURATION_ADDEVENT(leds_anim, param, commandIn.callback);
293 case ARDRONE_COMMAND_ENABLE_COMBINED_YAW:
295 bool_t enable = (bool_t)commandIn.parameter;
296 i_value = enable ? (ardrone_control_config.control_level | (1 << CONTROL_LEVEL_COMBINED_YAW)) : (ardrone_control_config.control_level & ~(1 << CONTROL_LEVEL_COMBINED_YAW));
297 ARDRONE_TOOL_CONFIGURATION_ADDEVENT(control_level, &i_value, commandIn.callback);
298 [hud combinedYawValueChanged:enable];
302 case ARDRONE_COMMAND_SET_CONFIG:
304 ARDRONE_CONFIG_PARAM *param = (ARDRONE_CONFIG_PARAM *)commandIn.parameter;
305 switch (param->config_key)
307 #undef COMMAND_IN_CONFIG_KEY
308 #undef COMMAND_IN_CONFIG_KEY_STRING
309 #define COMMAND_IN_CONFIG_KEY(CASE, KEY, TYPE) \
311 ardrone_control_config.KEY = *(TYPE *)(param->pvalue); \
312 ARDRONE_TOOL_CONFIGURATION_ADDEVENT (KEY, &ardrone_control_config.KEY, commandIn.callback); \
314 #define COMMAND_IN_CONFIG_KEY_STRING(CASE, KEY) \
316 strcpy (ardrone_control_config.KEY, (char *)(param->pvalue)); \
317 ARDRONE_TOOL_CONFIGURATION_ADDEVENT (KEY, ardrone_control_config.KEY, commandIn.callback); \
319 #include "ARDroneGeneratedCommandIn.h"
320 #undef COMMAND_IN_CONFIG_KEY
321 #undef COMMAND_IN_CONFIG_KEY_STRING
324 NSLog(@"The ARDRONE_CONFIG_KEY %d is not implemented !", param->config_key);
331 NSLog(@"The ARDRONE_COMMAND_IN %d is not implemented !", commandIn.command);
337 [menuSettings performSelectorOnMainThread:@selector(configChanged) withObject:nil waitUntilDone:YES];
341 - (void)executeCommandIn:(ARDRONE_COMMAND_IN)commandId withParameter:(void*)parameter fromSender:(id)sender
345 case ARDRONE_COMMAND_ISCLIENT:
347 i_value = ((int)parameter == 0) ? ADC_CMD_SELECT_ULTRASOUND_25Hz : ADC_CMD_SELECT_ULTRASOUND_22Hz;
348 ARDRONE_TOOL_CONFIGURATION_ADDEVENT(ultrasound_freq, &i_value, NULL);
352 case ARDRONE_COMMAND_DRONE_ANIM:
354 ARDRONE_ANIMATION_PARAM *param = (ARDRONE_ANIMATION_PARAM*)parameter;
355 char str_param[SMALL_STRING_SIZE];
356 sprintf(str_param, "%d,%d", param->drone_anim, ((param->timeout == 0) ? MAYDAY_TIMEOUT[param->drone_anim] : param->timeout));
357 ARDRONE_TOOL_CONFIGURATION_ADDEVENT(flight_anim, str_param, NULL);
361 case ARDRONE_COMMAND_VIDEO_CHANNEL:
362 i_value = (int32_t)parameter;
363 ARDRONE_TOOL_CONFIGURATION_ADDEVENT(video_channel, &i_value, NULL);
366 case ARDRONE_COMMAND_SET_FLY_MODE:
367 i_value = (int32_t)parameter;
368 ARDRONE_TOOL_CONFIGURATION_ADDEVENT(flying_mode, &i_value, NULL);
371 case ARDRONE_COMMAND_CAMERA_DETECTION:
372 i_value = (int32_t)parameter;
373 ARDRONE_TOOL_CONFIGURATION_ADDEVENT(detect_type, &i_value, NULL);
376 case ARDRONE_COMMAND_ENEMY_SET_PARAM:
377 i_value = ((ARDRONE_ENEMY_PARAM*)parameter)->color;
378 ARDRONE_TOOL_CONFIGURATION_ADDEVENT(enemy_colors, &i_value, NULL);
379 i_value = ((ARDRONE_ENEMY_PARAM*)parameter)->outdoor_shell;
380 ARDRONE_TOOL_CONFIGURATION_ADDEVENT(enemy_without_shell, &i_value, NULL);
383 case ARDRONE_COMMAND_DRONE_LED_ANIM:
385 char param[SMALL_STRING_SIZE];
387 freq.f = ((ARDRONE_LED_ANIMATION_PARAM*)parameter)->frequency;
388 sprintf(param, "%d,%d,%d", ((ARDRONE_LED_ANIMATION_PARAM*)parameter)->led_anim, freq.i, ((ARDRONE_LED_ANIMATION_PARAM*)parameter)->duration);
389 ARDRONE_TOOL_CONFIGURATION_ADDEVENT(leds_anim, param, NULL);
393 case ARDRONE_COMMAND_ENABLE_COMBINED_YAW:
395 bool_t enable = (bool_t)parameter;
396 i_value = enable ? (ardrone_control_config.control_level | (1 << CONTROL_LEVEL_COMBINED_YAW)) : (ardrone_control_config.control_level & ~(1 << CONTROL_LEVEL_COMBINED_YAW));
397 ARDRONE_TOOL_CONFIGURATION_ADDEVENT(control_level, &i_value, NULL);
398 [hud combinedYawValueChanged:enable];
403 NSLog(@"The ARDRONE_COMMAND_IN %d is not implemented !");
408 - (void)setDefaultConfigurationForKey:(ARDRONE_CONFIG_KEYS)key withValue:(void *)value
412 #undef COMMAND_IN_CONFIG_KEY
413 #undef COMMAND_IN_CONFIG_KEY_STRING
414 #define COMMAND_IN_CONFIG_KEY(CASE, KEY, TYPE) \
416 ardrone_application_default_config.KEY = *(TYPE *)(value); \
418 #define COMMAND_IN_CONFIG_KEY_STRING(CASE, KEY) \
420 strcpy (ardrone_application_default_config.KEY, (char *)(value)); \
422 #include "ARDroneGeneratedCommandIn.h"
423 #undef COMMAND_IN_CONFIG_KEY
424 #undef COMMAND_IN_CONFIG_KEY_STRING
426 NSLog(@"The ARDRONE_CONFIG_KEY %d is not implemented !", key);
431 - (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
433 return (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight || toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft);
436 - (void)didReceiveMemoryWarning
438 // Releases the view if it doesn't have a superview.
439 [super didReceiveMemoryWarning];
441 // Release any cached data, images, etc that aren't in use.
444 - (void)viewDidUnload {
445 // Release any retained subviews of the main view.
446 // e.g. self.myOutlet = nil;
451 [self changeState:NO];
455 [menuSettings release];