You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:03:21