功能:飞机在南京,人在北京,然后通过一个模拟摇杆(这个模拟摇杆就是一般玩飞行游戏的摇杆)控制南京的飞机飞行,也就是远程控制。这个摇杆类似于飞机遥控器的摇杆,一直输出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.不喜勿喷