使用DJI Android SDK自定义坐标实现Phantom 4跟随任务遇阻求助
问题分析与解决方案
咱们来拆解你遇到的核心问题:updateFollowingTarget() 无回调、无人机毫无反应,本质是异步操作处理逻辑错误加上SDK使用的细节疏漏。下面一步步说问题点和修复方案:
1. 最致命的错误:用Thread.sleep()阻塞主线程处理异步回调
你在调用updateFollowingTarget()后直接sleep 2.5秒,这会把主线程彻底卡住——而DJI SDK的所有回调(包括updateFollowingTarget的CompletionCallback)都是运行在主线程的!这意味着sleep期间,SDK根本没机会执行回调逻辑,甚至会导致SDK内部状态紊乱,后续startMission就算提示成功,无人机也因为目标坐标没真正更新而不执行动作。
修复方案:把startMission()的调用移到updateFollowingTarget()的成功回调里,等目标坐标更新确认成功后再启动任务,完全移除Thread.sleep():
private double lat = 48.5561726; private double lng = 12.1138481; private float initHeight = 10f; private LocationCoordinate2D targetLocation = new LocationCoordinate2D(lat + 0.0001d, lng); // 直接用枚举对象比较状态,避免toString的潜在问题 if (getFollowMeMissionOperator().getCurrentState() == FollowMeMissionState.READY_TO_EXECUTE) { getFollowMeMissionOperator().updateFollowingTarget(targetLocation, new CommonCallbacks.CompletionCallback() { @Override public void onResult(DJIError djiError) { if (djiError == null) { setResultToToast("Mission updateFollowingTarget: Successfully"); // 目标更新成功后,再启动任务 startFollowMeMission(targetLocation); } else { setResultToToast("Mission updateFollowingTarget: " + djiError.getDescription()); } } }); Log.println(Log.INFO,"FOLLOW", "Updating target coordinate..."); } else { Toast.makeText(getApplicationContext(), getFollowMeMissionOperator().getCurrentState().name(), Toast.LENGTH_SHORT).show(); } // 单独抽离启动任务的方法,逻辑更清晰 private void startFollowMeMission(LocationCoordinate2D target) { FollowMeMission mission = FollowMeMission.getInstance(); // 用已确认的目标坐标初始化任务 mission.initUserData(target.getLatitude(), target.getLongitude(), initHeight); getFollowMeMissionOperator().startMission(mission, new CommonCallbacks.CompletionCallback() { @Override public void onResult(DJIError djiError) { setResultToToast("Mission Start: " + (djiError == null ? "Successfully" : djiError.getDescription())); } }); }
2. 状态判断的不严谨:用toString()比较枚举值
你原来通过字符串比较判断FollowMe状态,这种写法很脆弱(比如枚举的toString实现可能随SDK版本变化)。直接用枚举对象比较才是正确姿势:
// 正确的状态判断方式 if (getFollowMeMissionOperator().getCurrentState() == FollowMeMissionState.READY_TO_EXECUTE) { // 执行后续逻辑 }
3. FollowMeMission初始化的细节注意
调用initUserData()时,要确保使用的是已经成功更新的目标坐标,同时要确认几个前置条件:
- 无人机已完成起飞并处于悬停状态
- GPS信号正常(至少6颗星以上,FollowMe依赖高精度定位)
- 无人机与遥控器连接稳定
- 已授予APP必要的权限(比如定位权限,即使自定义坐标,SDK也需要基础权限校验)
4. 为什么updateFollowingTarget()没有回调?
除了主线程被阻塞的核心原因,还有可能是:
- 调用
updateFollowingTarget()时,FollowMeOperator的状态在sleep期间发生了变化 - 自定义坐标值异常:可以打印
lat + 0.0001d的具体数值,确认是否在合理范围内 - SDK版本兼容问题:建议升级到最新的DJI Mobile SDK,老版本可能存在回调不触发的bug
按照上面的方案修改后,应该能解决回调缺失和无人机无反应的问题。
内容的提问来源于stack exchange,提问作者Andreas
相关产品推荐
相关产品推荐

