安卓利用大疆SDK的VirtualStick实现服务器端发送数据控制无人机飞行

功能:飞机在南京,人在北京,然后通过一个模拟摇杆(这个模拟摇杆就是一般玩飞行游戏的摇杆)控制南京的飞机飞行,也就是远程控制。这个摇杆类似于飞机遥控器的摇杆,一直输出yaw,pitch,roll的值,传到客户端后软件后进行一定的倍数转换,然后通过virtualstick模式去控制。

实现:1.服务器与客户端的连接我们用的是MQTT,这个根据自己项目的需求自己选择方式

           2.确定开始virtualstick模式,要先setVirtualStickModeEnabled为true,并且在设置成功后再去设置pitch,yaw,roll的模式

App.getAircraftInstance().getFlightController().setVirtualStickModeEnabled(true, new CommonCallbacks.CompletionCallback() {
                @Override
                public void onResult(DJIError djiError) {
                    if (null == djiError) {
                        isEnableStick = true;
                        Log.e("virstual", "enable success");
                        App.getAircraftInstance().getFlightController().setRollPitchControlMode(RollPitchControlMode.VELOCITY);
                        App.getAircraftInstance().getFlightController().setYawControlMode(YawControlMode.ANGULAR_VELOCITY);
                        App.getAircraftInstance().getFlightController().setVerticalControlMode(VerticalControlMode.VELOCITY);
                        App.getAircraftInstance().getFlightController().setRollPitchCoordinateSystem(FlightCoordinateSystem.BODY);
                    } else {
                        Log.e("virstual", "error = " + djiError.getDescription());
                    }
                }
            });

        3.然后可以开始对接收到的参数进行解析转换,最后通过sendVirtualStickFlightControlData去发送指令,官方给的发送频率要求是5-25HZ好像,也就是40毫秒至200毫秒发送一次。

/**
     * @param rockerX 杆量比[-1, 1], 前/后(+/-)
     * @param rockerY 杆量比[-1, 1], 左/右(-/+)
     * @param rockerZ 杆量比[-1, 1], 上/下(-/+)
     * @param rockerRotate 杆量比[-1, 1], 顺时针/逆时针(+/-)旋转
     */
    private FlightControlData senddata;

    private void fly(VirtualStickPB bean) {
        if (isEnableStick) {
            float rockX = (null == bean.rockerX ? 0 : bean.rockerX);
            float rockY = (null == bean.rockerY ? 0 : bean.rockerY);
            float rockZ = (null == bean.rockerZ ? 0 : bean.rockerZ);
            float rockerRotation = (null == bean.rockerRotation ? 0 : bean.rockerRotation);
            //Log.e("dispatch", "x = " + rockX + "   y = " + rockY + "  z = " + rockZ+"  rockerRotation = "+rockerRotation);

            RollPitchControlMode rollPitchControlMode = App.getAircraftInstance().getFlightController().getRollPitchControlMode();
            VerticalControlMode verticalControlMode = App.getAircraftInstance().getFlightController().getVerticalControlMode();
            YawControlMode yawControlMode = App.getAircraftInstance().getFlightController().getYawControlMode();

            if (rollPitchControlMode == RollPitchControlMode.VELOCITY) {
                // 前/后
                mRoll = rockX * Limits.ROLL_PITCH_CONTROL_MAX_VELOCITY;
                // 左/右
                mPitch = rockY * Limits.ROLL_PITCH_CONTROL_MAX_VELOCITY;
            } else if (rollPitchControlMode == RollPitchControlMode.ANGLE) {
                // 前/后
                mPitch = -rockX * Limits.ROLL_PITCH_CONTROL_MAX_ANGLE;
                // 左/右
                mRoll = rockY * Limits.ROLL_PITCH_CONTROL_MAX_ANGLE;
            } else {
                mPitch = 0;
                mRoll = 0;
            }

            if (verticalControlMode == VerticalControlMode.VELOCITY) {
                // 上/下
                mThrottle = -rockZ * Limits.VERTICAL_CONTROL_MAX_VELOCITY;
            } else if (verticalControlMode == VerticalControlMode.POSITION) {
                // 上/下
                if (rockZ >= 0) {
                    mThrottle = rockZ * Limits.VERTICAL_CONTROL_MAX_HEIGHT;
                } else {
                    mThrottle = 0;
                    //mThrottle = controller.getCurrentState().getAircraftLocation().getAltitude();
                }
            } else {
                mThrottle = 0;
            }

            if (yawControlMode == YawControlMode.ANGULAR_VELOCITY) {
                // 旋转
                mYaw = rockerRotation * Limits.YAW_CONTROL_MAX_ANGULAR_VELOCITY;
            } else if (yawControlMode == YawControlMode.ANGLE) {
                // 旋转
                mYaw = rockerRotation * Limits.YAW_CONTROL_MAX_ANGLE;
            } else {
                mYaw = 0;
            }

            senddata = new FlightControlData(mPitch, mRoll, mYaw, mThrottle);

            if (null == sendVirtualStickDataTimer) {
                sendVirtualStickDataTask = new SendVirtualStickDataTask();
                sendVirtualStickDataTimer = new Timer();
                sendVirtualStickDataTimer.schedule(sendVirtualStickDataTask, 100, 200);
            }
        } else {
            Log.e("dispatch", "isenablestick = false");
        }
    }

    private class SendVirtualStickDataTask extends TimerTask {
        @Override
        public void run() {
            if (ModuleVerificationUtil.isFlightControllerAvailable()) {
                App.getAircraftInstance().getFlightController().sendVirtualStickFlightControlData(senddata,
                        new CommonCallbacks.CompletionCallback() {
                            @Override
                            public void onResult(DJIError djiError) {

                            }
                        });
            } else {
                Log.e("SendVirtualStickData", "isFlightControllerAvailable = false");
            }
        }
    }

4.在结束的时候别忘了将virtualstick模式设为false,不然遥控器将控制不了飞机的貌似,然后该释放的资源释放掉

@Override
    public void onDestroy() {
        if (null != sendVirtualStickDataTimer) {
            if (sendVirtualStickDataTask != null) {
                sendVirtualStickDataTask.cancel();

            }
            sendVirtualStickDataTimer.cancel();
            sendVirtualStickDataTimer.purge();
            sendVirtualStickDataTimer = null;
            sendVirtualStickDataTask = null;
        }
        super.onDestroy();
        //Event.unregister(this);
    }

5.另外需要注意的事,大疆SDK必须登录账号,不然限制飞行50米,我曾经就被这个问题搞了很久,飞机为什么为了一段就不飞了,我一直觉得是我代码的问题,弄了两天才发现是没登录账号,很烦躁的。

我写的比较简单,实际可能会有其他一些问题,有问题跟我交流,QQ505057618.不喜勿喷

发布了24 篇原创文章 · 获赞 5 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_26923265/article/details/82743941