Difference between DJI onProductChange and onProductConnect

心已入冬 提交于 2021-01-29 08:03:37

问题


Context

I'm building a Flutter Plugin above the DJK SDK. For that, I have to implement the communication with the aircraft on the native side, and I'm doing it with Java. I'm also doing it only for Android.

One of the methods of the API is boolean connectToAircraft(), which must return if the connection with the aircraft succeeded.

Expected/current behavior

After I call connectToAircraft() - which invokes the DJISDKManager.getInstance().startConnectionToProduct() method, I expected to be able to use anything related to aircraft immediately, but this doesn't happen. I have to wait a few seconds before I can retrieve data from the aircraft.

Some code

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();
    }

    ...
}

Problem

The code above is what I tried to do, but it's not working and guess it's because I'm misunderstanding the use of the onProductChange() and onProductConnect() methods.

The DJISDKManager.getInstance().getProduct() is always returning null.

OBS: It's always returning null immediately after the onConnectToUavFinishedSignal.await() call finishes. After a few seconds, I get a valid instance of the aircraft.

Something I've also noticed is that sometimes the onProductChange() is called with some value that the log outputs as Unknwoun and None. What are those and how can I test for them? Like if (baseProduct == ???) doSomething()

Environment

  • Android 9
  • MSDK 4.13.1
  • Phantom 4 Pro

回答1:


Difference

According to the SDK Docs onProductChanged is primarily used to detect when the connection status changes from only remote controller connected to a full connection between the aircraft and the SDK running on your device.

Keep in mind that when the aircraft is disconnected, this method will be called with an instance of an aircraft, but this instance will come with property isConnected as false. If you print the aircraft object to the console you will notice that if isConnected is true, it will print the aircraft name, otherwise, it will print "None".

As long for the onProductConnect, it will be called always after DJISDKManager.getInstance().registerApp() succeeded or after you manually connect to the aircraft with success using DJISDKManager.getInstance().startConnectionToProduct(). In my tests, even though the app registration succeeds, the method will return false, so you might need to check if the SDKManagerCallback::onRegister results in DJISDKError.REGISTRATION_SUCCESS.

Solution

You need to listen to component change events. Unfortunately just because the product is connected it does not mean that the individual components, such as the flight controller, camera etc are connected. You will need to implement onComponentChange and add a listener to detect when a component is connected. These don't always connect in the same order and may start to connect before or after the product is connected.

@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();
      }
    }
  })
}


来源:https://stackoverflow.com/questions/64354240/difference-between-dji-onproductchange-and-onproductconnect

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!