2 #import <CoreMotion/CoreMotion.h>
4 // Ratio to activate control yaw and gaz
5 #define CONTROL_RATIO (1.0 / 3.0)
6 #define CONTROL_RATIO_IPAD (1.0 / 6.0)
8 #define ACCELERO_THRESHOLD 0.1
9 #define ACCELERO_NORM_THRESHOLD 0.0
10 #define ACCELERO_FASTMOVE_THRESHOLD 1.3
12 // Determine if a point within the boundaries of the joystick.
13 static bool_t isPointInCircle(CGPoint point, CGPoint center, float radius) {
14 float dx = (point.x - center.x);
15 float dy = (point.y - center.y);
16 return (radius >= sqrt( (dx * dx) + (dy * dy) ));
19 static float sign(float value)
28 static float Normalize(float x, float y, float z)
30 return sqrt(x * x + y * y + z * z);
33 static float Clamp(float v, float min, float max)
44 static CONTROLS controls_table[CONTROL_MODE_MAX] =
46 [CONTROL_MODE1] = { {FALSE, inputPitch, inputYaw}, {FALSE, inputGaz, inputRoll} },
47 [CONTROL_MODE2] = { {FALSE, inputGaz, inputYaw}, {TRUE, inputPitch, inputRoll} },
48 [CONTROL_MODE3] = { {TRUE, inputPitch, inputRoll}, {FALSE, inputGaz, inputYaw} },
49 [CONTROL_MODE4] = { {FALSE, inputGaz, inputRoll}, {FALSE, inputPitch, inputYaw} }
53 ControlData *controlData;
54 ARDroneHUDConfiguration config;
55 bool_t acceleroEnabled, combinedYawEnabled;
56 CONTROL_MODE controlMode;
58 float accelero_rotation[3][3];
59 UIAccelerationValue lastX, lastY, lastZ;
60 double lowPassFilterConstant, highPassFilterConstant;
61 BOOL accelerometer_started;
62 CGPoint joystickRightCurrentPosition, joystickLeftCurrentPosition;
63 CGPoint joystickRightInitialPosition, joystickLeftInitialPosition;
64 BOOL buttonRightPressed, buttonLeftPressed;
65 CGPoint rightCenter, leftCenter;
66 float tmp_phi, tmp_theta;
67 BOOL screenOrientationRight;
69 SystemSoundID plop_id, batt_id;
75 BOOL using2xInterface;
78 #if TARGET_IPHONE_SIMULATOR == 1
80 - (void)simulate_accelerometer:(id)sender;
83 - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration;
85 - (void)setAcceleroRotationWithPhi:(float)phi withTheta:(float)theta withPsi:(float)psi;
86 - (void)refreshJoystickRight;
87 - (void)refreshJoystickLeft;
88 - (void)updateVelocity:(CGPoint)point isRight:(BOOL)isRight;
91 - (void)refreshControlInterface;
95 @synthesize firePressed;
96 @synthesize settingsPressed;
97 @synthesize mainMenuPressed;
99 - (id)initWithFrame:(CGRect)frame withState:(BOOL)inGame withHUDConfiguration:(ARDroneHUDConfiguration)hudconfiguration withControlData:(ControlData*)data
101 NSArray *targetArray = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UIDeviceFamily"];
102 compiledForIPad = NO;
103 for (int i = 0; i < [targetArray count]; i++)
105 NSNumber* num = (NSNumber*)[targetArray objectAtIndex:i];
107 [num getValue:&value];
110 compiledForIPad = YES;
116 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
121 using2xInterface = NO;
122 if ([UIScreen instancesRespondToSelector:@selector(scale)]) {
123 CGFloat scale = [[UIScreen mainScreen] scale];
125 using2xInterface = YES;
129 if (usingIPad && compiledForIPad)
131 self = [super initWithNibName:@"HUD-iPad" bundle:nil];
135 self = [super initWithNibName:@"HUD" bundle:nil];
137 NSLog(@"HUD frame => w : %f, h : %f", data, frame.size.width, frame.size.height);
143 settingsPressed = NO;
144 mainMenuPressed = NO;
146 vp_os_memcpy(&config, &hudconfiguration, sizeof(ARDroneHUDConfiguration));
148 acceleroEnabled = TRUE;
149 combinedYawEnabled = FALSE;
150 controlMode = CONTROL_MODE3;
151 buttonRightPressed = buttonLeftPressed = NO;
153 rightCenter = CGPointZero;
154 leftCenter = CGPointZero;
155 lowPassFilterConstant = 0.2;
156 highPassFilterConstant = (1.0 / 5.0) / ((1.0 / kAPS) + (1.0 / 5.0));
158 joystickRightInitialPosition = CGPointZero;
159 joystickRightCurrentPosition = CGPointZero;
160 joystickLeftInitialPosition = CGPointZero;
161 joystickLeftCurrentPosition = CGPointZero;
170 [self setAcceleroRotationWithPhi:0.0 withTheta:0.0 withPsi:0.0];
172 accelerometer_started = NO;
174 #if TARGET_IPHONE_SIMULATOR == 1
175 [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)(1.0 / kAPS) target:self selector:@selector(simulate_accelerometer:) userInfo:nil repeats:YES];
177 [[UIAccelerometer sharedAccelerometer] setUpdateInterval: (NSTimeInterval)(1.0 / kAPS)];
178 [[UIAccelerometer sharedAccelerometer] setDelegate:self];
181 #ifdef WRITE_DEBUG_ACCELERO
183 NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) objectAtIndex:0];
184 sprintf(filename, "%s/accelero_iphones_mesures.txt",
185 [documentsDirectory cStringUsingEncoding:NSUTF8StringEncoding]);
186 mesures_file = fopen(filename, "wb");
187 fprintf(mesures_file, "ARDrone\nNumSamples;AccEnable;AccXbrut;AccYbrut;AccZbrut;AccX;AccY;AccZ;PhiAngle;ThetaAngle;AlphaAngle\n");
194 - (void) setAcceleroRotationWithPhi:(float)phi withTheta:(float)theta withPsi:(float)psi
196 accelero_rotation[0][0] = cosf(psi)*cosf(theta);
197 accelero_rotation[0][1] = -sinf(psi)*cosf(phi) + cosf(psi)*sinf(theta)*sinf(phi);
198 accelero_rotation[0][2] = sinf(psi)*sinf(phi) + cosf(psi)*sinf(theta)*cosf(phi);
199 accelero_rotation[1][0] = sinf(psi)*cosf(theta);
200 accelero_rotation[1][1] = cosf(psi)*cosf(phi) + sinf(psi)*sinf(theta)*sinf(phi);
201 accelero_rotation[1][2] = -cosf(psi)*sinf(phi) + sinf(psi)*sinf(theta)*cosf(phi);
202 accelero_rotation[2][0] = -sinf(theta);
203 accelero_rotation[2][1] = cosf(theta)*sinf(phi);
204 accelero_rotation[2][2] = cosf(theta)*cosf(phi);
206 #ifdef WRITE_DEBUG_ACCELERO
207 NSLog(@"Accelero rotation matrix changed :");
208 NSLog(@"%0.1f %0.1f %0.1f", accelero_rotation[0][0], accelero_rotation[0][1], accelero_rotation[0][2]);
209 NSLog(@"%0.1f %0.1f %0.1f", accelero_rotation[1][0], accelero_rotation[1][1], accelero_rotation[1][2]);
210 NSLog(@"%0.1f %0.1f %0.1f", accelero_rotation[2][0], accelero_rotation[2][1], accelero_rotation[2][2]);
214 #if TARGET_IPHONE_SIMULATOR == 1
215 - (void)simulate_accelerometer:(id)sender
217 UIAcceleration *acceleration = [[UIAcceleration alloc] init];
219 - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
222 static double highPassFilterX = 0.0, highPassFilterY = 0.0, highPassFilterZ = 0.0;
223 static bool_t prev_accelero_enabled = TRUE;
225 float accelerox, acceleroy, acceleroz;
226 highPassFilterX = highPassFilterConstant * (highPassFilterX + acceleration.x - lastX);
227 highPassFilterY = highPassFilterConstant * (highPassFilterY + acceleration.y - lastY);
228 highPassFilterZ = highPassFilterConstant * (highPassFilterZ + acceleration.z - lastZ);
229 lastX = acceleration.x;
230 lastY = acceleration.y;
231 lastZ = acceleration.z;
235 if(fabs(highPassFilterX) > ACCELERO_FASTMOVE_THRESHOLD ||
236 fabs(highPassFilterY) > ACCELERO_FASTMOVE_THRESHOLD ||
237 fabs(highPassFilterZ) > ACCELERO_FASTMOVE_THRESHOLD)
247 if(screenOrientationRight)
249 accelerox = acceleration.x;
250 acceleroy = -acceleration.y;
254 accelerox = -acceleration.x;
255 acceleroy = acceleration.y;
257 acceleroz = -acceleration.z;
259 // Initialize previous values of acceleros
260 if(accelerometer_started == NO)
262 accelerometer_started = YES;
263 accelero[0] = accelerox;
264 accelero[1] = acceleroy;
265 accelero[2] = acceleroz;
268 // Apply low pass filter on acceleros
269 accelero[0] = accelerox * lowPassFilterConstant + accelero[0] * (1.0 - lowPassFilterConstant);
270 accelero[1] = acceleroy * lowPassFilterConstant + accelero[1] * (1.0 - lowPassFilterConstant);
271 accelero[2] = acceleroz * lowPassFilterConstant + accelero[2] * (1.0 - lowPassFilterConstant);
273 // Apply rotation matrix and Clamp
274 accelerox = Clamp((accelero_rotation[0][0] * accelero[0]) + (accelero_rotation[0][1] * accelero[1]) + (accelero_rotation[0][2] * accelero[2]), -1.0, 1.0);
275 acceleroy = Clamp((accelero_rotation[1][0] * accelero[0]) + (accelero_rotation[1][1] * accelero[1]) + (accelero_rotation[1][2] * accelero[2]), -1.0, 1.0);
276 acceleroz = Clamp((accelero_rotation[2][0] * accelero[0]) + (accelero_rotation[2][1] * accelero[1]) + (accelero_rotation[2][2] * accelero[2]), -1.0, 1.0);
279 if(fabs(acceleroy) < ACCELERO_THRESHOLD)
288 alpha = atan2(accelerox, acceleroy);
291 norm = Normalize(accelerox, acceleroy, 0.0);
292 if(norm > ACCELERO_NORM_THRESHOLD)
294 float tmp = (norm - ACCELERO_NORM_THRESHOLD) * (norm - ACCELERO_NORM_THRESHOLD);
295 controlData->accelero_phi = tmp * cosf(alpha);
296 controlData->accelero_theta = -tmp * sinf(alpha);
300 controlData->accelero_phi = 0.0;
301 controlData->accelero_theta = 0.0;
304 else if(prev_accelero_enabled != acceleroEnabled)
306 controlData->accelero_phi = 0.0;
307 controlData->accelero_theta = 0.0;
310 prev_accelero_enabled = acceleroEnabled;
316 - (void)refreshJoystickRight
318 CGRect frame = joystickRightBackgroundImageView.frame;
319 frame.origin = joystickRightCurrentPosition;
320 joystickRightBackgroundImageView.frame = frame;
323 - (void)refreshJoystickLeft
325 CGRect frame = joystickLeftBackgroundImageView.frame;
326 frame.origin = joystickLeftCurrentPosition;
327 joystickLeftBackgroundImageView.frame = frame;
330 - (void)refreshControlInterface
334 switch (controlMode) {
336 joystickLeftBackgroundImageView.hidden = NO;
337 joystickRightBackgroundImageView.hidden = YES;
342 joystickLeftBackgroundImageView.hidden = YES;
343 joystickRightBackgroundImageView.hidden = NO;
349 joystickLeftBackgroundImageView.hidden = NO;
350 joystickRightBackgroundImageView.hidden = NO;
353 [self refreshJoystickRight];
354 [self refreshJoystickLeft];
357 - (void)changeState:(BOOL)inGame
359 printf("%s - running : %d, inGame : %d\n", __FUNCTION__, running, inGame);
363 if(buttonRightPressed)
364 [joystickRightButton sendActionsForControlEvents:UIControlEventTouchCancel];
366 if(buttonLeftPressed)
367 [joystickLeftButton sendActionsForControlEvents:UIControlEventTouchCancel];
371 - (void)acceleroValueChanged:(bool_t)enabled
373 acceleroEnabled = enabled;
374 [self performSelectorOnMainThread:@selector(refreshControlInterface) withObject:nil waitUntilDone:YES];
377 - (void)combinedYawValueChanged:(bool_t)enabled
379 combinedYawEnabled = enabled;
380 [self performSelectorOnMainThread:@selector(refreshControlInterface) withObject:nil waitUntilDone:YES];
383 - (void)interfaceAlphaValueChanged:(CGFloat)value
385 joystickRightThumbImageView.alpha = value;
386 joystickRightBackgroundImageView.alpha = value;
387 joystickLeftThumbImageView.alpha = value;
388 joystickLeftBackgroundImageView.alpha = value;
392 - (void)controlModeChanged:(CONTROL_MODE)mode
395 [self performSelectorOnMainThread:@selector(refreshControlInterface) withObject:nil waitUntilDone:YES];
398 - (void)updateVelocity:(CGPoint)point isRight:(BOOL)isRight
400 CGPoint nextpoint = CGPointMake(point.x, point.y);
401 CGPoint center = (isRight ? rightCenter : leftCenter);
402 UIImageView *backgroundImage = (isRight ? joystickRightBackgroundImageView : joystickLeftBackgroundImageView);
403 UIImageView *thumbImage = (isRight ? joystickRightThumbImageView : joystickLeftThumbImageView);
405 // Calculate distance and angle from the center.
406 float dx = nextpoint.x - center.x;
407 float dy = nextpoint.y - center.y;
409 float distance = sqrt(dx * dx + dy * dy);
410 float angle = atan2(dy, dx); // in radians
412 // NOTE: Velocity goes from -1.0 to 1.0.
413 // BE CAREFUL: don't just cap each direction at 1.0 since that
414 // doesn't preserve the proportions.
415 float joystick_radius = backgroundImage.frame.size.width / 2;
416 if (distance > joystick_radius) {
417 dx = cos(angle) * joystick_radius;
418 dy = sin(angle) * joystick_radius;
421 // Constrain the thumb so that it stays within the joystick
422 // boundaries. This is smaller than the joystick radius in
423 // order to account for the size of the thumb.
424 float thumb_radius = thumbImage.frame.size.width / 2;
425 if (distance > thumb_radius) {
426 nextpoint.x = center.x + (cos(angle) * thumb_radius);
427 nextpoint.y = center.y + (sin(angle) * thumb_radius);
430 // Update the thumb's position
431 CGRect frame = thumbImage.frame;
432 frame.origin.x = nextpoint.x - (thumbImage.frame.size.width / 2);
433 frame.origin.y = nextpoint.y - (thumbImage.frame.size.height / 2);
434 thumbImage.frame = frame;
437 - (void)setMessageBox:(NSString*)str
439 static int prevSound = 0;
440 [messageBoxLabel performSelectorOnMainThread:@selector(setText:) withObject:str waitUntilDone:YES];
442 struct timeval nowSound;
443 gettimeofday(&nowSound, NULL);
444 if (([str compare:ARDroneEngineLocalizeString(@"BATTERY LOW ALERT")] == NSOrderedSame) &&
445 2 < (nowSound.tv_sec - prevSound))
447 AudioServicesPlaySystemSound(batt_id);
448 prevSound = nowSound.tv_sec;
452 - (void)setTakeOff:(NSString*)str
454 UIImage *image = [UIImage imageNamed:[str stringByAppendingString:@".png"]];
455 [takeOffButton setImage:image forState:UIControlStateNormal];
458 - (void)setEmergency:(NSString*)str
460 if([str length] != 0)
462 UIImage *image = [UIImage imageNamed:[str stringByAppendingString:@".png"]];
463 emergencyButton.enabled = TRUE;
464 emergencyButton.alpha = 1.0;
465 [emergencyButton setImage:image forState:UIControlStateNormal];
469 emergencyButton.enabled = FALSE;
470 emergencyButton.alpha = 0.5;
476 batteryLevelLabel.hidden = YES;
477 batteryImageView.hidden = YES;
482 batteryLevelLabel.hidden = (config.enableBatteryPercentage == NO);
483 batteryImageView.hidden = NO;
487 - (void)enableBackToMainMenu
489 backToMainMenuButton.enabled = YES;
490 backToMainMenuButton.alpha = 1.0;
493 - (void)disableBackToMainMenu
495 backToMainMenuButton.enabled = NO;
496 backToMainMenuButton.alpha = 0.0;
499 - (void)showBackToMainMenu:(BOOL)show
502 [self performSelectorOnMainThread:@selector(enableBackToMainMenu) withObject:nil waitUntilDone:YES];
504 [self performSelectorOnMainThread:@selector(disableBackToMainMenu) withObject:nil waitUntilDone:YES];
507 - (void)setBattery:(int)percent
511 [self performSelectorOnMainThread:@selector(hideInfos) withObject:nil waitUntilDone:YES];
515 UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"battery%d.png", ((percent < 10) ? 0 : (int)((percent / 33.4) + 1))]];
516 [batteryImageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];
518 [self performSelectorOnMainThread:@selector(showInfos) withObject:nil waitUntilDone:YES];
520 [batteryLevelLabel performSelectorOnMainThread:@selector(setTextColor:) withObject:((percent < 10) ? [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:0.7] : [UIColor colorWithRed:0.0 green:0.65 blue:0.0 alpha:0.7]) waitUntilDone:YES];
521 [batteryLevelLabel performSelectorOnMainThread:@selector(setText:) withObject:[NSString stringWithFormat:@"%d %%", percent] waitUntilDone:YES];
525 - (IBAction)buttonPress:(id)sender forEvent:(UIEvent *)event
527 UITouch *touch = [[event touchesForView:sender] anyObject];
528 CGPoint point = [touch locationInView:self.view];
529 bool_t acceleroModeOk = NO;
531 if(sender == joystickRightButton)
533 buttonRightPressed = YES;
534 // Start only if the first touch is within the pad's boundaries.
535 // Allow touches to be tracked outside of the pad as long as the
536 // screen continues to be pressed.
537 BOOL joystickIsOutside = ((point.x + (joystickRightBackgroundImageView.frame.size.width / 2) > (joystickRightButton.frame.origin.x + joystickRightButton.frame.size.width)) ||
538 (point.x - (joystickRightBackgroundImageView.frame.size.width / 2) < joystickRightButton.frame.origin.x) ||
539 (point.y + (joystickRightBackgroundImageView.frame.size.height / 2) > (joystickRightButton.frame.origin.y + joystickRightButton.frame.size.height)) ||
540 (point.y - (joystickRightBackgroundImageView.frame.size.height / 2) < joystickRightButton.frame.origin.y));
542 if(joystickIsOutside)
544 AudioServicesPlaySystemSound(plop_id);
547 joystickRightCurrentPosition.x = point.x - (joystickRightBackgroundImageView.frame.size.width / 2);
548 joystickRightCurrentPosition.y = point.y - (joystickRightBackgroundImageView.frame.size.height / 2);
550 joystickRightBackgroundImageView.alpha = joystickRightThumbImageView.alpha = 1.0;
553 [self refreshJoystickRight];
556 rightCenter = CGPointMake(joystickRightBackgroundImageView.frame.origin.x + (joystickRightBackgroundImageView.frame.size.width / 2), joystickRightBackgroundImageView.frame.origin.y + (joystickRightBackgroundImageView.frame.size.height / 2));
559 [self updateVelocity:rightCenter isRight:YES];
561 acceleroModeOk = controls_table[controlMode].Right.can_use_accelero;
563 if(combinedYawEnabled && buttonLeftPressed)
564 controlData->accelero_flag |= (1 << ARDRONE_PROGRESSIVE_CMD_COMBINED_YAW_ACTIVE);
566 else if(sender == joystickLeftButton)
568 buttonLeftPressed = YES;
570 joystickLeftCurrentPosition.x = point.x - (joystickLeftBackgroundImageView.frame.size.width / 2);
571 joystickLeftCurrentPosition.y = point.y - (joystickLeftBackgroundImageView.frame.size.height / 2);
573 joystickLeftBackgroundImageView.alpha = joystickLeftThumbImageView.alpha = 1.0;
576 [self refreshJoystickLeft];
579 leftCenter = CGPointMake(joystickLeftBackgroundImageView.frame.origin.x + (joystickLeftBackgroundImageView.frame.size.width / 2), joystickLeftBackgroundImageView.frame.origin.y + (joystickLeftBackgroundImageView.frame.size.height / 2));
582 [self updateVelocity:leftCenter isRight:NO];
584 acceleroModeOk = controls_table[controlMode].Left.can_use_accelero;
585 if(combinedYawEnabled && buttonRightPressed)
586 controlData->accelero_flag |= (1 << ARDRONE_PROGRESSIVE_CMD_COMBINED_YAW_ACTIVE);
591 controlData->accelero_flag |= (1 << ARDRONE_PROGRESSIVE_CMD_ENABLE);
594 // Start only if the first touch is within the pad's boundaries.
595 // Allow touches to be tracked outside of the pad as long as the
596 // screen continues to be pressed.
598 phi = (float)atan2f(accelero[1], accelero[2]);
599 theta = -(float)atan2f(accelero[0] * cosf(phi), accelero[2]);
600 [self setAcceleroRotationWithPhi:phi withTheta:theta withPsi:0.0];
605 - (IBAction)buttonRelease:(id)sender forEvent:(UIEvent *)event
607 bool_t acceleroModeOk = NO;
608 if(sender == joystickRightButton)
610 buttonRightPressed = NO;
612 // Reinitialize joystick position
613 joystickRightCurrentPosition = joystickRightInitialPosition;
614 joystickRightBackgroundImageView.alpha = joystickRightThumbImageView.alpha = alpha;
617 [self refreshJoystickRight];
620 rightCenter = CGPointMake(joystickRightBackgroundImageView.frame.origin.x + (joystickRightBackgroundImageView.frame.size.width / 2), joystickRightBackgroundImageView.frame.origin.y + (joystickRightBackgroundImageView.frame.size.height / 2));
623 [self updateVelocity:rightCenter isRight:YES];
625 controls_table[controlMode].Right.up_down(0.0);
626 controls_table[controlMode].Right.left_right(0.0);
628 acceleroModeOk = controls_table[controlMode].Right.can_use_accelero;
630 if(combinedYawEnabled)
631 controlData->accelero_flag &= ~(1 << ARDRONE_PROGRESSIVE_CMD_COMBINED_YAW_ACTIVE);
633 else if(sender == joystickLeftButton)
635 //printf("button left released\n");
636 buttonLeftPressed = NO;
637 // Reinitialize joystick position
638 joystickLeftCurrentPosition = joystickLeftInitialPosition;
639 joystickLeftBackgroundImageView.alpha = joystickLeftThumbImageView.alpha = alpha;
642 [self refreshJoystickLeft];
645 leftCenter = CGPointMake(joystickLeftBackgroundImageView.frame.origin.x + (joystickLeftBackgroundImageView.frame.size.width / 2), joystickLeftBackgroundImageView.frame.origin.y + (joystickLeftBackgroundImageView.frame.size.height / 2));
648 [self updateVelocity:leftCenter isRight:NO];
650 controls_table[controlMode].Left.up_down(0.0);
651 controls_table[controlMode].Left.left_right(0.0);
653 acceleroModeOk = controls_table[controlMode].Left.can_use_accelero;
655 if(combinedYawEnabled)
656 controlData->accelero_flag &= ~(1 << ARDRONE_PROGRESSIVE_CMD_COMBINED_YAW_ACTIVE);
661 controlData->accelero_flag &= ~(1 << ARDRONE_PROGRESSIVE_CMD_ENABLE);
664 [self setAcceleroRotationWithPhi:0.0 withTheta:0.0 withPsi:0.0];
669 - (IBAction)buttonDrag:(id)sender forEvent:(UIEvent *)event
671 UITouch *touch = [[event touchesForView:sender] anyObject];
672 CGPoint point = [touch locationInView:self.view];
673 bool_t acceleroModeOk = NO;
676 float controlRatio = 0.5 - (CONTROL_RATIO / 2.0);
677 if (usingIPad && compiledForIPad)
679 controlRatio = 0.5 - (CONTROL_RATIO_IPAD / 2.0);
684 if(sender == joystickRightButton)
686 if((rightCenter.x - point.x) > ((joystickRightBackgroundImageView.frame.size.width / 2) - (controlRatio * joystickRightBackgroundImageView.frame.size.width)))
688 float percent = ((rightCenter.x - point.x) - ((joystickRightBackgroundImageView.frame.size.width / 2) - (controlRatio * joystickRightBackgroundImageView.frame.size.width))) / ((controlRatio * joystickRightBackgroundImageView.frame.size.width));
689 //NSLog(@"Percent (left) : %f\n", percent);
692 controls_table[controlMode].Right.left_right(-percent);
694 else if((point.x - rightCenter.x) > ((joystickRightBackgroundImageView.frame.size.width / 2) - (controlRatio * joystickRightBackgroundImageView.frame.size.width)))
696 float percent = ((point.x - rightCenter.x) - ((joystickRightBackgroundImageView.frame.size.width / 2) - (controlRatio * joystickRightBackgroundImageView.frame.size.width))) / ((controlRatio * joystickRightBackgroundImageView.frame.size.width));
697 //NSLog(@"Percent (right) : %f\n", percent);
700 controls_table[controlMode].Right.left_right(percent);
704 controls_table[controlMode].Right.left_right(0.0);
707 if((point.y - rightCenter.y) > ((joystickRightBackgroundImageView.frame.size.height / 2) - (controlRatio * joystickRightBackgroundImageView.frame.size.height)))
709 float percent = ((point.y - rightCenter.y) - ((joystickRightBackgroundImageView.frame.size.height / 2) - (controlRatio * joystickRightBackgroundImageView.frame.size.height))) / ((controlRatio * joystickRightBackgroundImageView.frame.size.height));
710 //NSLog(@"Percent (down) : %f\n", percent);
713 controls_table[controlMode].Right.up_down(-percent);
715 else if((rightCenter.y - point.y) > ((joystickRightBackgroundImageView.frame.size.height / 2) - (controlRatio * joystickRightBackgroundImageView.frame.size.height)))
717 float percent = ((rightCenter.y - point.y) - ((joystickRightBackgroundImageView.frame.size.height / 2) - (controlRatio * joystickRightBackgroundImageView.frame.size.height))) / ((controlRatio * joystickRightBackgroundImageView.frame.size.height));
718 //NSLog(@"Percent (top) : %f\n", percent);
721 controls_table[controlMode].Right.up_down(percent);
725 controls_table[controlMode].Right.up_down(0.0);
728 acceleroModeOk = controls_table[controlMode].Right.can_use_accelero;
730 else if(sender == joystickLeftButton)
732 if((leftCenter.x - point.x) > ((joystickLeftBackgroundImageView.frame.size.width / 2) - (controlRatio * joystickLeftBackgroundImageView.frame.size.width)))
734 float percent = ((leftCenter.x - point.x) - ((joystickLeftBackgroundImageView.frame.size.width / 2) - (controlRatio * joystickLeftBackgroundImageView.frame.size.width))) / ((controlRatio * joystickLeftBackgroundImageView.frame.size.width));
737 controls_table[controlMode].Left.left_right(-percent);
739 else if((point.x - leftCenter.x) > ((joystickLeftBackgroundImageView.frame.size.width / 2) - (controlRatio * joystickLeftBackgroundImageView.frame.size.width)))
741 float percent = ((point.x - leftCenter.x) - ((joystickLeftBackgroundImageView.frame.size.width / 2) - (controlRatio * joystickLeftBackgroundImageView.frame.size.width))) / ((controlRatio * joystickLeftBackgroundImageView.frame.size.width));
744 controls_table[controlMode].Left.left_right(percent);
748 controls_table[controlMode].Left.left_right(0.0);
751 if((point.y - leftCenter.y) > ((joystickLeftBackgroundImageView.frame.size.height / 2) - (controlRatio * joystickLeftBackgroundImageView.frame.size.height)))
753 float percent = ((point.y - leftCenter.y) - ((joystickLeftBackgroundImageView.frame.size.height / 2) - (controlRatio * joystickLeftBackgroundImageView.frame.size.height))) / ((controlRatio * joystickLeftBackgroundImageView.frame.size.height));
756 controls_table[controlMode].Left.up_down(-percent);
758 else if((leftCenter.y - point.y) > ((joystickLeftBackgroundImageView.frame.size.height / 2) - (controlRatio * joystickLeftBackgroundImageView.frame.size.height)))
760 float percent = ((leftCenter.y - point.y) - ((joystickLeftBackgroundImageView.frame.size.height / 2) - (controlRatio * joystickLeftBackgroundImageView.frame.size.height))) / ((controlRatio * joystickLeftBackgroundImageView.frame.size.height));
763 controls_table[controlMode].Left.up_down(percent);
767 controls_table[controlMode].Left.up_down(0.0);
770 acceleroModeOk = controls_table[controlMode].Left.can_use_accelero;
777 // Update joystick velocity
778 [self updateVelocity:point isRight:(sender == joystickRightButton)];
783 // Update joystick velocity
784 [self updateVelocity:point isRight:(sender == joystickRightButton)];
789 - (IBAction)buttonClick:(id)sender forEvent:(UIEvent *)event
791 static ARDRONE_VIDEO_CHANNEL channel = ARDRONE_VIDEO_CHANNEL_FIRST;
792 if(sender == settingsButton)
793 settingsPressed = YES;
794 else if(sender == backToMainMenuButton)
795 mainMenuPressed = YES;
796 else if(sender == switchScreenButton)
798 if(channel++ == ARDRONE_VIDEO_CHANNEL_LAST)
799 channel = ARDRONE_VIDEO_CHANNEL_FIRST;
801 ARDRONE_TOOL_CONFIGURATION_ADDEVENT(video_channel, (int32_t*)&channel, NULL);
803 else if(sender == takeOffButton)
807 else if(sender == emergencyButton)
815 switchScreenButton.hidden = (config.enableSwitchScreen == NO);
816 backToMainMenuButton.hidden = (config.enableBackToMainMenu == NO);
817 batteryLevelLabel.hidden = (config.enableBatteryPercentage == NO);
819 rightCenter = CGPointMake(joystickRightThumbImageView.frame.origin.x + (joystickRightThumbImageView.frame.size.width / 2), joystickRightThumbImageView.frame.origin.y + (joystickRightThumbImageView.frame.size.height / 2));
820 joystickRightInitialPosition = CGPointMake(rightCenter.x - (joystickRightBackgroundImageView.frame.size.width / 2), rightCenter.y - (joystickRightBackgroundImageView.frame.size.height / 2));
821 leftCenter = CGPointMake(joystickLeftThumbImageView.frame.origin.x + (joystickLeftThumbImageView.frame.size.width / 2), joystickLeftThumbImageView.frame.origin.y + (joystickLeftThumbImageView.frame.size.height / 2));
822 joystickLeftInitialPosition = CGPointMake(leftCenter.x - (joystickLeftBackgroundImageView.frame.size.width / 2), leftCenter.y - (joystickLeftBackgroundImageView.frame.size.height / 2));
824 joystickLeftCurrentPosition = joystickLeftInitialPosition;
825 joystickRightCurrentPosition = joystickRightInitialPosition;
827 alpha = MIN(joystickRightBackgroundImageView.alpha, joystickRightThumbImageView.alpha);
828 joystickRightBackgroundImageView.alpha = joystickRightThumbImageView.alpha = alpha;
829 joystickLeftBackgroundImageView.alpha = joystickLeftThumbImageView.alpha = alpha;
831 // Get the URL to the sound file to play
832 CFURLRef batt_url = CFBundleCopyResourceURL (CFBundleGetMainBundle(),
836 CFURLRef plop_url = CFBundleCopyResourceURL (CFBundleGetMainBundle(),
841 // Create a system sound object representing the sound file
842 AudioServicesCreateSystemSoundID (plop_url, &plop_id);
843 AudioServicesCreateSystemSoundID (batt_url, &batt_id);
847 [self setBattery:-1];
852 #ifdef WRITE_DEBUG_ACCELERO
853 fclose(mesures_file);
855 AudioServicesDisposeSystemSoundID (plop_id);
856 AudioServicesDisposeSystemSoundID (batt_id);