コード例 #1
0
ファイル: MainActivity.cs プロジェクト: joaomajesus/TelloLib
        public void OnTouchJoystickMoved(JoystickView joystickView)
        {
            if (isPaused)//Zero out any movement when paused.
            {
                Tello.controllerState.setAxis(0, 0, 0, 0);
            }
            else
            {
                Tello.controllerState.setAxis(onScreenJoyL.normalizedX, -onScreenJoyL.normalizedY, onScreenJoyR.normalizedX, -onScreenJoyR.normalizedY);
            }

            Tello.sendControllerUpdate();
        }
コード例 #2
0
ファイル: MainActivity.cs プロジェクト: latentdev/TelloLib
        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);

            //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)
                {
                    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.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)

                    Tello.setEV(Preferences.exposure);
                }
                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(() => {
                    cbutton.Text = newState.ToString();
                    if (newState == Tello.ConnectionState.Connected)
                    {
                        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());
            }

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

                RunOnUiThread(() => {
                    //Update state on screen

                    modeTextView.Text   = "FM:" + newState.flyMode;
                    hSpeedTextView.Text = string.Format("HS:{0: 0.0;-0.0}m/s", (float)newState.flySpeed / 10);
                    vSpeedTextView.Text = string.Format("VS:{0: 0.0;-0.0}m/s", (float)newState.verticalSpeed / 10);
                    heiTextView.Text    = string.Format("Hei:{0: 0.0;-0.0}m", (float)newState.height / 10);

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

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

                    //acstat.Text = str;
                    if (Tello.state.flying)
                    {
                        takeoffButton.SetImageResource(Resource.Drawable.land);
                    }
                    else if (!Tello.state.flying)
                    {
                        takeoffButton.SetImageResource(Resource.Drawable.takeoff_white);
                    }
                });
            };

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

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

            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
            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;
                                    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));
                }
            };


            takeoffButton.Click += delegate {
                if (Tello.connected && !Tello.state.flying)
                {
                    Tello.takeOff();
                }
                else if (Tello.connected && Tello.state.flying)
                {
                    Tello.land();
                }
            };
            throwTakeoffButton.Click += 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);


            cameraShutterSound.Load("cameraShutterClick.mp3");
            pictureButton.Click += delegate
            {
                Tello.takePicture();
                cameraShutterSound.Play();
            };
            pictureButton.LongClick += delegate
            {
                //Toggle
                picMode = picMode == 1?0:1;
                Tello.setPicVidMode(picMode);
                aTello.Video.Decoder.reconfig();
            };

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

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

            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();
        }
コード例 #3
0
ファイル: MainActivity.cs プロジェクト: latentdev/TelloLib
 public void OnTouchJoystickMoved(JoystickView joystickView)
 {
     Tello.controllerState.setAxis(onScreenJoyL.normalizedX, -onScreenJoyL.normalizedY, onScreenJoyR.normalizedX, -onScreenJoyR.normalizedY);
     Tello.sendControllerUpdate();
 }
コード例 #4
0
ファイル: MainActivity.cs プロジェクト: joaomajesus/TelloLib
        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();
        }