private void Tello_onConnection(Tello.ConnectionState newState)
 {
     if (newState == Tello.ConnectionState.Connected)
     {
         Debug.Log("Connected to Tello, please wait for camera feed");
         Tello.setPicVidMode(1); // 0: picture, 1: video
         Tello.setVideoBitRate((int)TelloController.VideoBitRate.VideoBitRateAuto);
         Tello.requestIframe();
     }
 }
Esempio n. 2
0
 private void Tello_onConnection(Tello.ConnectionState newState)
 {
     //throw new System.NotImplementedException();
     //Debug.Log("Tello_onConnection : " + newState);
     if (newState == Tello.ConnectionState.Connected)
     {
         Tello.setPicVidMode(1);             // 0: picture, 1: video
         Tello.setVideoBitRate((int)Tello.VideoBitRate.VideoBitRateAuto);
         //Tello.setEV(0);
         Tello.requestIframe();
     }
 }
Esempio n. 3
0
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            this.RequestWindowFeature(WindowFeatures.NoTitle);
            this.Window.AddFlags(WindowManagerFlags.Fullscreen | WindowManagerFlags.TurnScreenOn);
            SetContentView(Resource.Layout.Settings);

            var items = new List <int>()
            {
                0, 1, 2, 3, 4, 5, 6
            };
            var axisAdapter = new ArrayAdapter <int>(this, Android.Resource.Layout.SimpleSpinnerItem, items);
            var spinner     = FindViewById <Spinner>(Resource.Id.lxSpinner);

            spinner.Adapter = axisAdapter;
            spinner.SetSelection(Preferences.lxAxis);
            spinner.ItemSelected += (sender, args) =>
            {
                Preferences.lxAxis = args.Position;
                Preferences.save();
            };

            spinner         = FindViewById <Spinner>(Resource.Id.lySpinner);
            spinner.Adapter = axisAdapter;
            spinner.SetSelection(Preferences.lyAxis);
            spinner.ItemSelected += (sender, args) =>
            {
                Preferences.lyAxis = args.Position;
                Preferences.save();
            };

            spinner         = FindViewById <Spinner>(Resource.Id.rxSpinner);
            spinner.Adapter = axisAdapter;
            spinner.SetSelection(Preferences.rxAxis);
            spinner.ItemSelected += (sender, args) =>
            {
                Preferences.rxAxis = args.Position;
                Preferences.save();
            };

            spinner         = FindViewById <Spinner>(Resource.Id.rySpinner);
            spinner.Adapter = axisAdapter;
            spinner.SetSelection(Preferences.ryAxis);
            spinner.ItemSelected += (sender, args) =>
            {
                Preferences.ryAxis = args.Position;
                Preferences.save();
            };


            var joyItems = new List <string>()
            {
                "Generic", "PS3/PS4"
            };
            var joyAdapter     = new ArrayAdapter <string>(this, Android.Resource.Layout.SimpleSpinnerItem, joyItems);
            var joyTypeSpinner = FindViewById <Spinner>(Resource.Id.joystickTypeSpinner);

            joyTypeSpinner.Adapter = joyAdapter;
            joyTypeSpinner.SetSelection(Preferences.joyType);
            joyTypeSpinner.ItemSelected += (sender, args) =>
            {
                Preferences.setJoyType(args.Position);
                Preferences.save();
            };

            var evItems = new List <double>()
            {
                -3.0, -2.7, -2.3, -2.0, -1.7, -1.3, -1.0, -0.7, -0.3, 0, 0.3, 0.7, 1.0, 1.3, 1.7, 2.0, 2.3, 2.7, 3.0
            };
            var evAdapter = new ArrayAdapter <double>(this, Android.Resource.Layout.SimpleSpinnerItem, evItems);
            var evSpinner = FindViewById <Spinner>(Resource.Id.exposureSpinner);

            evSpinner.Adapter = evAdapter;
            evSpinner.SetSelection(Preferences.exposure);
            evSpinner.ItemSelected += (sender, args) =>
            {
                Preferences.exposure = args.Position;
                Tello.setEV(Preferences.exposure);

                Preferences.save();
            };

            var vbrItems = new List <string>()
            {
                "Auto", "1M", "1.5M", "2M", "3M", "4M", "5", "6"
            };
            var vbrAdapter = new ArrayAdapter <string>(this, Android.Resource.Layout.SimpleSpinnerItem, vbrItems);
            var vbrSpinner = FindViewById <Spinner>(Resource.Id.vbrSpinner);

            vbrSpinner.Adapter = vbrAdapter;
            vbrSpinner.SetSelection(Preferences.videoBitRate);
            vbrSpinner.ItemSelected += (sender, args) =>
            {
                Preferences.videoBitRate = args.Position;
                Tello.setVideoBitRate(Preferences.videoBitRate);

                Preferences.save();
            };
            //2,5,10,20,40
            var iframeRateItems = new List <string>()
            {
                "10/s", "4/s", "2/s", "1/s", "0.5/s"
            };
            var iframeRateAdapter = new ArrayAdapter <string>(this, Android.Resource.Layout.SimpleSpinnerItem, iframeRateItems);
            var iframeRateSpinner = FindViewById <Spinner>(Resource.Id.iframeRateSpinner);

            iframeRateSpinner.Adapter = iframeRateAdapter;
            switch (Preferences.iFrameRate)
            {
            case 2:
                iframeRateSpinner.SetSelection(0);
                break;

            case 5:
                iframeRateSpinner.SetSelection(1);
                break;

            case 10:
                iframeRateSpinner.SetSelection(2);
                break;

            case 20:
                iframeRateSpinner.SetSelection(3);
                break;

            case 40:
                iframeRateSpinner.SetSelection(4);
                break;
            }
            iframeRateSpinner.ItemSelected += (sender, args) =>
            {
                switch (args.Position)
                {
                case 0:
                    Preferences.iFrameRate = 2;
                    break;

                case 1:
                    Preferences.iFrameRate = 5;
                    break;

                case 2:
                    Preferences.iFrameRate = 10;
                    break;

                case 3:
                    Preferences.iFrameRate = 20;
                    break;

                case 4:
                    Preferences.iFrameRate = 40;
                    break;
                }
                Tello.iFrameRate = Preferences.iFrameRate;
                Preferences.save();
            };


            var cacheVideoSwitch = FindViewById <Switch>(Resource.Id.cacheVideoSwitch);

            cacheVideoSwitch.Checked        = Preferences.cacheVideo;
            cacheVideoSwitch.CheckedChange += (sender, args) =>
            {
                Preferences.cacheVideo = args.IsChecked;
                Preferences.save();
            };


            var photoQualitySwitch = FindViewById <Switch>(Resource.Id.photoQualitySwitch);

            photoQualitySwitch.Checked        = Preferences.jpgQuality > 0;
            photoQualitySwitch.CheckedChange += (sender, args) =>
            {
                Preferences.jpgQuality = args.IsChecked ? 1 : 0;
                Preferences.save();
                Tello.setJpgQuality(Preferences.jpgQuality);
            };

            //Settings button
            Button convertVideoButton = FindViewById <Button>(Resource.Id.convertVideoButton);

            convertVideoButton.Click += async delegate
            {
                if (true)
                {
                    try
                    {
                        FileData fileData = await CrossFilePicker.Current.PickFile();

                        if (fileData == null)
                        {
                            return; // user canceled file picking
                        }
                        string fileName = fileData.FileName;
                        //string contents = System.Text.Encoding.UTF8.GetString(fileData.DataArray);
                        Console.WriteLine(fileData.FilePath);

                        System.Console.WriteLine("File name chosen: " + fileName);
                        //System.Console.WriteLine("File data: " + contents);

                        RunOnUiThread(async() => {
                            var videoConverter = new aTello.VideoConverter();
                            var result         = await videoConverter.ConvertFileAsync(this, new Java.IO.File(fileData.FilePath));
                            Toast.MakeText(Application.Context, "Video Converted. Result:" + result, ToastLength.Long).Show();
                        });
                    }
                    catch (Exception ex)
                    {
                        System.Console.WriteLine("Exception choosing file: " + ex.ToString());
                    }
                    return;
                }
            };


            Button convertAllVideoButton = FindViewById <Button>(Resource.Id.convertAllVideoButton);

            convertAllVideoButton.Click += async delegate
            {
                var          path  = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, "aTello/video/");
                Java.IO.File f     = new Java.IO.File(path);
                var          files = f.ListFiles().ToList();

                //append cache files to list.
                path = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, "aTello/video/cache");
                f    = new Java.IO.File(path);
                files.AddRange(f.ListFiles());

                foreach (Java.IO.File inFile in files)
                {
                    if (!inFile.IsDirectory && inFile.Name.EndsWith(".h264"))
                    {
                        RunOnUiThread(async() =>
                        {
                            var videoConverter = new aTello.VideoConverter();
                            var inF            = new Java.IO.File(inFile.Path);
                            var result         = await videoConverter.ConvertFileAsync(this, inF);
                            Toast.MakeText(Application.Context, "Video Converted. Result:" + result, ToastLength.Long).Show();
                            if (result != null)
                            {
                                inF.Delete();
                            }
                        });
                    }
                }
            };
            //EditText text = FindViewById<EditText>(Resource.Id.maxHeightText);
            //text.AfterTextChanged += delegate {
            //    Tello.setMaxHeight(int.Parse(text.Text));
            //};
            //text = FindViewById<EditText>(Resource.Id.exposureText);
            //text.AfterTextChanged += delegate {
            //    Tello.setEV(int.Parse(text.Text));
            //};
            //text = FindViewById<EditText>(Resource.Id.attAngleText);
            //text.AfterTextChanged += delegate {
            //    Tello.setAttAngle(int.Parse(text.Text));
            //};
            //text = FindViewById<EditText>(Resource.Id.eisText);
            //text.AfterTextChanged += delegate {
            //    Tello.setEIS(int.Parse(text.Text));
            //};
        }
Esempio n. 4
0
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.Main);

            //force max brightness on screen.
            Window.Attributes.ScreenBrightness = 1f;

            //Full screen and hide nav bar.
            View decorView    = Window.DecorView;
            var  uiOptions    = (int)decorView.SystemUiVisibility;
            var  newUiOptions = (int)uiOptions;

            newUiOptions |= (int)SystemUiFlags.LowProfile;
            newUiOptions |= (int)SystemUiFlags.Fullscreen;
            newUiOptions |= (int)SystemUiFlags.HideNavigation;
            newUiOptions |= (int)SystemUiFlags.Immersive;
            // This option will make bars disappear by themselves
            newUiOptions |= (int)SystemUiFlags.ImmersiveSticky;
            decorView.SystemUiVisibility = (StatusBarVisibility)newUiOptions;

            //Keep screen from dimming.
            this.Window.SetFlags(WindowManagerFlags.KeepScreenOn, WindowManagerFlags.KeepScreenOn);


            onScreenJoyL = FindViewById <JoystickView>(Resource.Id.joystickViewL);
            onScreenJoyR = FindViewById <JoystickView>(Resource.Id.joystickViewR);

            takeoffButton      = FindViewById <ImageButton>(Resource.Id.takeoffButton);
            throwTakeoffButton = FindViewById <ImageButton>(Resource.Id.throwTakeoffButton);

            rthButton = FindViewById <ImageButton>(Resource.Id.rthButton);

            //subscribe to Tello connection events
            Tello.onConnection += (Tello.ConnectionState newState) =>
            {
                //Update state on screen
                Button cbutton = FindViewById <Button>(Resource.Id.connectButton);

                //If not connected check to see if connected to tello network.
                if (newState != Tello.ConnectionState.Connected &&
                    newState != Tello.ConnectionState.Paused)
                {
                    WifiManager wifiManager = (WifiManager)Application.Context.GetSystemService(Context.WifiService);
                    string      ip          = Formatter.FormatIpAddress(wifiManager.ConnectionInfo.IpAddress);
                    if (!ip.StartsWith("192.168.10."))
                    {
                        //CrossTextToSpeech.Current.Speak("No network found.");
                        //Not connected to network.
                        RunOnUiThread(() => {
                            cbutton.Text = "Not Connected. Touch Here.";
                            cbutton.SetBackgroundColor(Android.Graphics.Color.ParseColor("#55ff3333"));
                        });
                        return;
                    }
                }
                if (newState == Tello.ConnectionState.Paused)
                {
                }
                if (newState == Tello.ConnectionState.UnPausing)
                {
                }
                if (newState == Tello.ConnectionState.Connected)
                {
                    //Tello.queryMaxHeight();
                    //Override max hei on connect.
                    Tello.setMaxHeight(30);//meters
                    Tello.queryMaxHeight();

                    //Tello.queryAttAngle();
                    Tello.setAttAngle(25);
                    //Tello.queryAttAngle();

                    Tello.setJpgQuality(Preferences.jpgQuality);

                    CrossTextToSpeech.Current.Speak("Connected");

                    Tello.setPicVidMode(picMode);//0=picture(960x720)
                    //updateVideoSize();

                    Tello.setEV(Preferences.exposure);

                    Tello.setVideoBitRate(Preferences.videoBitRate);
                    Tello.setVideoDynRate(1);

                    if (forceSpeedMode)
                    {
                        Tello.controllerState.setSpeedMode(1);
                    }
                    else
                    {
                        Tello.controllerState.setSpeedMode(0);
                    }
                }
                if (newState == Tello.ConnectionState.Disconnected)
                {
                    //if was connected then warn.
                    if (Tello.connectionState == Tello.ConnectionState.Connected)
                    {
                        CrossTextToSpeech.Current.Speak("Disconnected");
                    }
                }
                //update connection state button.
                RunOnUiThread(() => {
                    if (newState == Tello.ConnectionState.UnPausing)//Fix. Don't show "unpausing" string.
                    {
                        cbutton.Text = Tello.ConnectionState.Connected.ToString();
                    }
                    else
                    {
                        cbutton.Text = newState.ToString();
                    }

                    if (newState == Tello.ConnectionState.Connected || newState == Tello.ConnectionState.UnPausing)
                    {
                        cbutton.SetBackgroundColor(Android.Graphics.Color.ParseColor("#6090ee90"));//transparent light green.
                    }
                    else
                    {
                        cbutton.SetBackgroundColor(Android.Graphics.Color.ParseColor("#ffff00"));//yellow
                    }
                });
            };
            var modeTextView   = FindViewById <TextView>(Resource.Id.modeTextView);
            var hSpeedTextView = FindViewById <TextView>(Resource.Id.hSpeedTextView);
            var vSpeedTextView = FindViewById <TextView>(Resource.Id.vSpeedTextView);
            var heiTextView    = FindViewById <TextView>(Resource.Id.heiTextView);
            var batTextView    = FindViewById <TextView>(Resource.Id.batTextView);
            var wifiTextView   = FindViewById <TextView>(Resource.Id.wifiTextView);

            //Log file setup.
            var logPath      = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, "aTello/logs/");;
            var logStartTime = DateTime.Now;
            var logFilePath  = logPath + logStartTime.ToString("yyyy-dd-M--HH-mm-ss") + ".csv";

            if (doStateLogging)
            {
                //write header for cols in log.
                System.IO.Directory.CreateDirectory(logPath);
                File.WriteAllText(logFilePath, "time," + Tello.state.getLogHeader());
            }

            //Long click vert speed to force fast mode.
            hSpeedTextView.LongClick += delegate {
                forceSpeedMode = !forceSpeedMode;
                if (forceSpeedMode)
                {
                    Tello.controllerState.setSpeedMode(1);
                }
                else
                {
                    Tello.controllerState.setSpeedMode(0);
                }
            };

            cameraShutterSound.Load("cameraShutterClick.mp3");
            //subscribe to Tello update events
            Tello.onUpdate += (int cmdId) =>
            {
                if (doStateLogging)
                {
                    //write update to log.
                    var elapsed = DateTime.Now - logStartTime;
                    File.AppendAllText(logFilePath, elapsed.ToString(@"mm\:ss\:ff\,") + Tello.state.getLogLine());
                }

                RunOnUiThread(() => {
                    if (cmdId == 86)//ac status update.
                    {
                        //Update state on screen
                        modeTextView.Text   = "FM:" + Tello.state.flyMode;
                        hSpeedTextView.Text = string.Format("HS:{0: 0.0;-0.0}m/s", (float)Tello.state.flySpeed / 10);
                        vSpeedTextView.Text = string.Format("VS:{0: 0.0;-0.0}m/s", -(float)Tello.state.verticalSpeed / 10);//Note invert so negative means moving down.
                        heiTextView.Text    = string.Format("Hei:{0: 0.0;-0.0}m", (float)Tello.state.height / 10);

                        if (Tello.controllerState.speed > 0)
                        {
                            hSpeedTextView.SetBackgroundColor(Android.Graphics.Color.IndianRed);
                        }
                        else
                        {
                            hSpeedTextView.SetBackgroundColor(Android.Graphics.Color.DarkGreen);
                        }

                        batTextView.Text  = "Bat:" + Tello.state.batteryPercentage;
                        wifiTextView.Text = "Wifi:" + Tello.state.wifiStrength;

                        //Autopilot debugging.
                        if (/*!bAutopilot &&*/ Tello.state.flying)
                        {
                            RunOnUiThread(() =>
                            {
                                var eular = Tello.state.toEuler();
                                var yaw   = eular[2];

                                var deltaPosX   = autopilotTarget.X - Tello.state.posX;
                                var deltaPosY   = autopilotTarget.Y - Tello.state.posY;
                                var dist        = Math.Sqrt(deltaPosX * deltaPosX + deltaPosY * deltaPosY);
                                var normalizedX = deltaPosX / dist;
                                var normalizedY = deltaPosY / dist;

                                var targetYaw = Math.Atan2(normalizedY, normalizedX);
                                var deltaYaw  = targetYaw - yaw;

                                var str = string.Format("x {0:0.00; -0.00} y {1:0.00; -0.00} yaw {2:0.00; -0.00} targetYaw {3:0.00; -0.00} targetDist {4:0.00; -0.00} On:{5}",
                                                        Tello.state.posX, Tello.state.posY,
                                                        (((yaw * (180.0 / Math.PI)) + 360.0) % 360.0),
                                                        (((targetYaw * (180.0 / Math.PI)) + 360.0) % 360.0), dist,
                                                        bAutopilot.ToString());

                                TextView joystat = FindViewById <TextView>(Resource.Id.joystick_state);
                                joystat.Text     = str;
                            });
                        }



                        //acstat.Text = str;
                        if (Tello.state.flying)
                        {
                            takeoffButton.SetImageResource(Resource.Drawable.land);
                        }
                        else if (!Tello.state.flying)
                        {
                            takeoffButton.SetImageResource(Resource.Drawable.takeoff_white);
                        }
                    }
                    if (cmdId == 48)//ack picture start.
                    {
                        cameraShutterSound.Play();
                    }
                    if (cmdId == 98)//start picture download.
                    {
                    }
                    if (cmdId == 100)                      //picture piece downloaded.
                    {
                        if (Tello.picDownloading == false) //if done downloading.
                        {
                            if (remainingExposures >= 0)
                            {
                                var exposureSet = new int[] { 0, -2, 8 };
                                Tello.setEV(Preferences.exposure + exposureSet[remainingExposures]);
                                remainingExposures--;
                                Tello.takePicture();
                            }
                            if (remainingExposures == -1)//restore exposure.
                            {
                                Tello.setEV(Preferences.exposure);
                            }
                        }
                    }
                });

                //Do autopilot input.
                handleAutopilot();
            };



            var videoFrame  = new byte[100 * 1024];
            var videoOffset = 0;

            updateVideoSize();
            Video.Decoder.surface = FindViewById <SurfaceView>(Resource.Id.surfaceView).Holder.Surface;

/*
 *          var textureView = FindViewById<TextureView>(Resource.Id.textureView);
 *          mSurfaceTextureListener = new SurfaceTextureListener(this);
 *          textureView.SurfaceTextureListener = mSurfaceTextureListener;
 *
 *          //var st = new Surface(textureView.SurfaceTexture);
 *          //Video.Decoder.surface = st;
 *
 */

            var path = "aTello/video/";

            System.IO.Directory.CreateDirectory(Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, path + "cache/"));
            videoFilePath = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, path + "cache/" + DateTime.Now.ToString("MMMM dd yyyy HH-mm-ss") + ".h264");

            FileStream videoStream = null;

            startUIUpdateThread();
            //updateUI();//hide record light etc.

            //subscribe to Tello video data
            var vidCount = 0;

            Tello.onVideoData += (byte[] data) =>
            {
                totalVideoBytesReceived += data.Length;
                //Handle recording.
                if (true)                                                             //videoFilePath != null)
                {
                    if (data[2] == 0 && data[3] == 0 && data[4] == 0 && data[5] == 1) //if nal
                    {
                        var nalType = data[6] & 0x1f;
                        //                       if (nalType == 7 || nalType == 8)
                        {
                            if (toggleRecording)
                            {
                                if (videoStream != null)
                                {
                                    videoStream.Close();
                                }
                                videoStream = null;

                                isRecording     = !isRecording;
                                toggleRecording = false;
                                if (isRecording)
                                {
                                    videoFilePath      = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, path + DateTime.Now.ToString("MMMM dd yyyy HH-mm-ss") + ".h264");
                                    startRecordingTime = DateTime.Now;
//                                    Tello.setVideoRecord(vidCount++);
                                    CrossTextToSpeech.Current.Speak("Recording");
                                    updateUI();
                                }
                                else
                                {
                                    videoFilePath = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, path + "cache/" + DateTime.Now.ToString("MMMM dd yyyy HH-mm-ss") + ".h264");
                                    CrossTextToSpeech.Current.Speak("Recording stopped");
                                    updateUI();
                                }
                            }
                        }
                    }

                    if ((isRecording || Preferences.cacheVideo))
                    {
                        if (videoStream == null)
                        {
                            videoStream = new FileStream(videoFilePath, FileMode.Append);
                        }

                        if (videoStream != null)
                        {
                            //Save raw data minus sequence.
                            videoStream.Write(data, 2, data.Length - 2);//Note remove 2 byte seq when saving.
                        }
                    }
                }

                //Handle video display.
                if (true)//video decoder tests.
                {
                    //Console.WriteLine("1");

                    if (data[2] == 0 && data[3] == 0 && data[4] == 0 && data[5] == 1)//if nal
                    {
                        var nalType = data[6] & 0x1f;
                        if (nalType == 7 || nalType == 8)
                        {
                        }
                        if (videoOffset > 0)
                        {
                            aTello.Video.Decoder.decode(videoFrame.Take(videoOffset).ToArray());
                            videoOffset = 0;
                        }
                        //var nal = (received.bytes[6] & 0x1f);
                        //if (nal != 0x01 && nal != 0x07 && nal != 0x08 && nal != 0x05)
                        //    Console.WriteLine("NAL type:" + nal);
                    }
                    //todo. resquence frames.
                    Array.Copy(data, 2, videoFrame, videoOffset, data.Length - 2);
                    videoOffset += (data.Length - 2);
                }
            };

            onScreenJoyL.onUpdate += OnTouchJoystickMoved;
            onScreenJoyR.onUpdate += OnTouchJoystickMoved;



            Tello.startConnecting();//Start trying to connect.

            //Clicking on network state button will show wifi connection page.
            Button button = FindViewById <Button>(Resource.Id.connectButton);

            button.Click += delegate {
                WifiManager wifiManager = (WifiManager)Application.Context.GetSystemService(Context.WifiService);
                string      ip          = Formatter.FormatIpAddress(wifiManager.ConnectionInfo.IpAddress);
                if (!ip.StartsWith("192.168.10."))//Already connected to network?
                {
                    StartActivity(new Intent(Android.Net.Wifi.WifiManager.ActionPickWifiNetwork));
                }
            };

            rthButton.LongClick += delegate {
                bAutopilot = !bAutopilot;//Toggle autopilot
            };
            rthButton.Click += delegate {
                bAutopilot = false;//Stop if going.
                Tello.controllerState.setAxis(0, 0, 0, 0);
                Tello.sendControllerUpdate();

                //set new home point
                setAutopilotTarget(new PointF(Tello.state.posX, Tello.state.posY));
            };

            takeoffButton.LongClick += delegate {
                if (Tello.connected && !Tello.state.flying)
                {
                    Tello.takeOff();
                }
                else if (Tello.connected && Tello.state.flying)
                {
                    Tello.land();
                }
            };
            throwTakeoffButton.LongClick += delegate {
                if (Tello.connected && !Tello.state.flying)
                {
                    Tello.throwTakeOff();
                }
                else if (Tello.connected && Tello.state.flying)
                {
                    //Tello.land();
                }
            };
            var pictureButton = FindViewById <ImageButton>(Resource.Id.pictureButton);

            Tello.picPath = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, "aTello/pics/");
            System.IO.Directory.CreateDirectory(Tello.picPath);

            pictureButton.Click += delegate
            {
                remainingExposures = -1;
                Tello.takePicture();
            };

            /*
             * Multiple exposure. Not working yet.
             * pictureButton.LongClick += delegate
             * {
             *  remainingExposures = 2;
             *  Tello.takePicture();
             * };
             */

            var recordButton = FindViewById <ImageButton>(Resource.Id.recordButton);

            recordButton.Click += delegate
            {
                toggleRecording = true;
            };

            recordButton.LongClick += delegate
            {
                //Toggle
                picMode = picMode == 1 ? 0 : 1;
                Tello.setPicVidMode(picMode);
                updateVideoSize();
                aTello.Video.Decoder.reconfig();
            };
            var galleryButton = FindViewById <ImageButton>(Resource.Id.galleryButton);

            galleryButton.Click += async delegate
            {
                //var uri = Android.Net.Uri.FromFile(new Java.IO.File(Tello.picPath));
                //shareImage(uri);
                //return;
                Intent intent = new Intent();
                intent.PutExtra(Intent.ActionView, Tello.picPath);
                intent.SetType("image/*");
                intent.SetAction(Intent.ActionGetContent);
                StartActivityForResult(Intent.CreateChooser(intent, "Select Picture"), 1);
            };
            //Settings button
            ImageButton settingsButton = FindViewById <ImageButton>(Resource.Id.settingsButton);

            settingsButton.Click += delegate
            {
                StartActivity(typeof(SettingsActivity));
            };


            //Init joysticks.
            input_manager = (InputManager)GetSystemService(Context.InputService);
            CheckGameControllers();
        }