DJI onProductChange 和 onProductConnect 的区别

Difference between DJI onProductChange and onProductConnect

上下文

我正在 DJK SDK 之上构建一个 Flutter 插件。为此,我必须在本机端实现与飞机的通信,我正在使用 Java 来实现。我也只为 Android.

这样做

API的方法之一是boolean connectToAircraft(),必须return连接飞行器成功

Expected/current行为

在我调用 connectToAircraft() 之后 - 它调用了 DJISDKManager.getInstance().startConnectionToProduct() 方法,我希望能够立即使用与飞机相关的任何东西,但这并没有发生。我得等几秒钟才能从飞机上取回数据

一些代码

public class UavApi implements IUavApi, DJISDKManager.SDKManagerCallback {
    ...
    
    private final CountDownLatch onConnectToUavFinishedSignal = new CountDownLatch(1);
    
    ...
    
    public boolean connectToUav() throws InterruptedException {
        Logger.v("connectToUav()");

        DJISDKManager.getInstance().startConnectionToProduct();

        synchronized (onConnectToUavFinishedSignal) {
            onConnectToUavFinishedSignal.await();
        }

        return DJISDKManager.getInstance().getProduct() instanceof Aircraft;
    }
    
    ...
    
    @Override
    public void onProductConnect(@Nullable final BaseProduct baseProduct) {
        Logger.v(MessageFormat.format("onProductConnect(product: {0})", baseProduct));

        if (baseProduct != null) {
          handleProductConnected(baseProduct);
        }
    }

    @Override
    public void onProductChanged(@Nullable final BaseProduct baseProduct) {
        Logger.v(MessageFormat.format("onProductChanged(product: {0})", baseProduct));

        if (baseProduct != null) {
          handleProductConnected(baseProduct);
        }
    }

    ...

    private void handleProductConnected(@NonNull final BaseProduct baseProduct) {
        Logger.d(MessageFormat.format("Is null? {0}", baseProduct == null ? "Yes" : "No"));
        Logger.d(MessageFormat.format("Type: {0}", baseProduct.getClass().getSimpleName()));
        
        onConnectToUavFinishedSignal.countDown();
    }

    ...
}

问题

上面的代码是我尝试做的,但它不起作用,我猜这是因为我误解了 onProductChange()onProductConnect() 方法的使用。

DJISDKManager.getInstance().getProduct() 总是 returning null。

OBS:总是在 onConnectToUavFinishedSignal.await() 调用结束后立即 returning null。几秒钟后,我得到了飞机的有效实例。

我还注意到,有时调用 onProductChange() 时会使用日志输出的某些值作为 Unknwoun 和 None。这些是什么?我如何测试它们?喜欢if (baseProduct == ???) doSomething()

环境

差异

根据SDK DocsonProductChanged主要用于检测连接状态从只连接遥控器变为全连接飞行器与SDK运行设备。

请记住,当飞机断开连接时,将使用飞机实例调用此方法,但此实例将与 属性 isConnected 一起作为 false。如果将飞机对象打印到控制台,您会注意到如果 isConnectedtrue,它将打印飞机名称,否则将打印“None”。

只要onProductConnect,总是会在DJISDKManager.getInstance().registerApp()成功后或手动连接飞行器DJISDKManager.getInstance().startConnectionToProduct()成功后调用。在我的测试中,即使应用程序注册成功,该方法也会 return false,因此您可能需要检查 SDKManagerCallback::onRegister 是否导致 DJISDKError.REGISTRATION_SUCCESS.

解决方案

您需要监听组件变化事件。不幸的是,仅仅因为产品已连接,并不意味着飞行控制器、摄像头等各个组件都已连接。您将需要实施 onComponentChange 并添加侦听器以检测组件何时连接。这些并不总是以相同的顺序连接,可能会在连接产品之前或之后开始连接。

@Override
public void onComponentChange(
  BaseProduct.ComponentKey componentKey,
  BaseComponent oldBaseComponent,
  BaseComponent newBaseComponent
) {
  newBaseComponent.setComponentListener(isConnected -> {
    // check if component connected and access data
    if (isConnected) {
      if(componentKey == ComponentKey.FLIGHT_CONTROLLER) {
        // DJISDKManager.getInstance().getProduct() should no longer be null
        DJISDKManager.getInstance().getProduct().getModel();
      }
    }
  })
}