Please select Into the mobile phone version | Continue to access the computer ver.
Close
You need to log in before you can reply       Login | Register now

[Android] Executing TapFly Mission

Author: Jeanlim96 2017-8-11 10:59
5 66
Hi I am unsure as to what the setup environment method of the TapFlyMissionOperator Class does. Currently I am encountering problems implementing the TapFlyMission. The djierror that comes up is 'the execution could not be executed' each time I try to start the mission. Another error that comes up sometimes is 'the execution has timed out'. The steps that I have undertaken to try to execute the mission are as follows:

public class TapFlyActivity extends DemoBaseActivity implements SurfaceTextureListener, OnClickListener, OnTouchListener {
   
    private static final String TAG = "TapFlyActivity";
   
    private TapFlyMissionOperator instance;
    private TapFlyMission mTapFlyMission;

    private ImageButton mPushDrawerIb;
    private SlidingDrawer mPushDrawerSd;
    private Button mStartBtn;
    private ImageButton mStopBtn;
    private TextView mTapFlyTv;
    private RelativeLayout mBgLayout;
    private ImageView mRstPointIv;
    private TextView mAssisTv;
    private Switch mAssisSw;
    private TextView mSpeedTv;
    private SeekBar mSpeedSb;

    private void setResultToToast(final String string) {
        TapFlyActivity.this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(TapFlyActivity.this, string, Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void setResultToText(final String string) {
        TapFlyActivity.this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mTapFlyTv.setText(string);
            }
        });
    }

    public TapFlyMissionOperator getTapFlyMissionOperator() {
        if (instance == null) {
            instance = DJISDKManager.getInstance().getMissionControl().getTapFlyMissionOperator();
        }
        return instance;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        setContentView(R.layout.activity_pointing_test);
        super.onCreate(savedInstanceState);
        initUI();
        addListener();
    }

    private void initUI() {
        mPushDrawerIb = (ImageButton)findViewById(R.id.pointing_drawer_control_ib);
        mPushDrawerSd = (SlidingDrawer)findViewById(R.id.pointing_drawer_sd);
        mStartBtn = (Button)findViewById(R.id.pointing_start_btn);
        mStopBtn = (ImageButton)findViewById(R.id.pointing_stop_btn);
        mTapFlyTv = (TextView)findViewById(R.id.pointing_push_tv);
        mBgLayout = (RelativeLayout)findViewById(R.id.pointing_bg_layout);
        mRstPointIv = (ImageView)findViewById(R.id.pointing_rst_point_iv);
        mAssisTv = (TextView)findViewById(R.id.pointing_assistant_tv);
        mAssisSw = (Switch)findViewById(R.id.pointing_assistant_sw);
        mSpeedTv = (TextView)findViewById(R.id.pointing_speed_tv);
        mSpeedSb = (SeekBar)findViewById(R.id.pointing_speed_sb);

        mPushDrawerIb.setOnClickListener(this);
        mStartBtn.setOnClickListener(this);
        mStopBtn.setOnClickListener(this);
        mBgLayout.setOnTouchListener(this);
        mSpeedSb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                mSpeedTv.setText(progress + 1 + "");
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                if (getTapFlyMissionOperator() != null){
                    getTapFlyMissionOperator().setAutoFlightSpeed(getSpeed(), new CompletionCallback() {

                        @Override
                        public void onResult(DJIError error) {
                            setResultToToast(error == null ? "Success" : error.getDescription());
                        }
                    });
                }
            }
        });
    }

    private float getSpeed() {
        if (mSpeedSb == null) return Float.NaN;
        return mSpeedSb.getProgress() + 1;
    }

    //Add Listener for TapFlyMissionOperator
    private void addListener() {
        Aircraft aircraft = DJIDemoApplication.getAircraftInstance();
        if (aircraft != null && aircraft.isConnected() && getTapFlyMissionOperator() != null) {
            getTapFlyMissionOperator().addListener(eventNotificationListener);
        }
    }

    private TapFlyMissionOperatorListener eventNotificationListener = new TapFlyMissionOperatorListener() {
        @Override
        public void onUpdate(@Nullable TapFlyMissionEvent tapFlyMissionEvent) {
            TapFlyExecutionState TapFlyStatus = tapFlyMissionEvent.getProgressState();
            if (TapFlyStatus != null){
                StringBuffer sb = new StringBuffer();
                Utils.addLineToSB(sb, "Mission state", tapFlyMissionEvent.getCurrentState().getName());
                Utils.addLineToSB(sb, "Flight direction X (North)", TapFlyStatus.getDirection().getX());
                Utils.addLineToSB(sb, "Flight direction Y (East)", TapFlyStatus.getDirection().getY());
                Utils.addLineToSB(sb, "Flight direction Z (Down)", TapFlyStatus.getDirection().getZ());
                Utils.addLineToSB(sb, "Image point x", TapFlyStatus.getImageLocation().x);
                Utils.addLineToSB(sb, "Image point y", TapFlyStatus.getImageLocation().y);
                Utils.addLineToSB(sb, "Speed (m/s)", TapFlyStatus.getSpeed());
                Utils.addLineToSB(sb, "Bypass state", TapFlyStatus.getBypassDirection().name());
                Utils.addLineToSB(sb, "Error", tapFlyMissionEvent.getError() == null ? "No Errors" : tapFlyMissionEvent.getError().getDescription());
                setResultToText(sb.toString());
                showPointByTapFlyPoint(TapFlyStatus.getImageLocation(), mRstPointIv);
            } else {
                StringBuffer sb = new StringBuffer();
                Utils.addLineToSB(sb, "Mission state", tapFlyMissionEvent.getCurrentState().getName());
                setResultToText(sb.toString());
            }

        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        mTapFlyMission = new TapFlyMission();
    }

    @Override
    protected void onDestroy() {

        if(mCodecManager != null){
            mCodecManager.destroyCodec();
        }
        removeListener();
        super.onDestroy();
    }

    private void removeListener() {
        Aircraft aircraft = DJIDemoApplication.getAircraftInstance();
        if (aircraft != null && aircraft.isConnected() && getTapFlyMissionOperator() != null) {
            getTapFlyMissionOperator().removeListener(eventNotificationListener);
        }
    }

    public void onReturn(View view){
        Log.d(TAG, "onReturn");
        this.finish();
    }

    private void setVisible(final View v, final boolean visible) {
        if (v == null) return;
        TapFlyActivity.this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                v.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
            }
        });
    }


    private PointF getTapFlyPoint(View iv) {
        if (iv == null) return null;
        View parent = (View)iv.getParent();
        float centerX = iv.getLeft() + iv.getX()  + ((float)iv.getWidth()) / 2;
        float centerY = iv.getTop() + iv.getY() + ((float)iv.getHeight()) / 2;
        centerX = centerX < 0 ? 0 : centerX;
        centerX = centerX > parent.getWidth() ? parent.getWidth() : centerX;
        centerY = centerY < 0 ? 0 : centerY;
        centerY = centerY > parent.getHeight() ? parent.getHeight() : centerY;
        
        return new PointF(centerX / parent.getWidth(), centerY / parent.getHeight());
    }
   
    private void showPointByTapFlyPoint(final PointF point, final ImageView iv) {
        if (point == null || iv == null) {
            return;
        }
        final View parent = (View)iv.getParent();
         TapFlyActivity.this.runOnUiThread(new Runnable() {

             @Override
             public void run() {
                 iv.setX(point.x * parent.getWidth() - iv.getWidth() / 2);
                 iv.setY(point.y * parent.getHeight() - iv.getHeight() / 2);
                 iv.setVisibility(View.VISIBLE);
                 iv.requestLayout();
             }
         });
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (v.getId() == R.id.pointing_bg_layout) {
            
            switch (event.getAction()) {
            case MotionEvent.ACTION_UP:
                if (getTapFlyMissionOperator() != null) {
                    mStartBtn.setVisibility(View.VISIBLE);
                    mStartBtn.setX(event.getX() - mStartBtn.getWidth() / 2);
                    mStartBtn.setY(event.getY() - mStartBtn.getHeight() / 2);
                    mStartBtn.requestLayout();
                    mTapFlyMission.target = getTapFlyPoint(mStartBtn);
                    mTapFlyMission.tapFlyMode = TapFlyMode.FORWARD;
                    getTapFlyMissionOperator().setupEnvironment(new CompletionCallback() {

                        @Override
                        public void onResult(DJIError error) {
                            if (error == null) {
                                setVisible(mStartBtn, true);
                            } else {
                                setVisible(mStartBtn, false);
                            }
                            setResultToToast("Set up environment: " + (error == null ? "Success" : error.getDescription()));
                        }
                    });
                } else {
                    setResultToToast("TapFly Mission Operator is null");
                }
                break;

            default:
                break;
            }
        }
        return true;
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.pointing_drawer_control_ib) {
            if (mPushDrawerSd.isOpened()) {
                mPushDrawerSd.animateClose();
            } else {
                mPushDrawerSd.animateOpen();
            }
            return;
        }
        if (getTapFlyMissionOperator() != null) {
            switch (v.getId()) {
            case R.id.pointing_start_btn:
                mTapFlyMission.speed = getSpeed();
                mTapFlyMission.isHorizontalObstacleAvoidanceEnabled = mAssisSw.isChecked();


                getTapFlyMissionOperator().startMission(mTapFlyMission, new CompletionCallback() {

                    @Override
                    public void onResult(DJIError error) {
                        if (error == null) {
                            setVisible(mStartBtn, false);
                            setVisible(mStopBtn, true);
                            setVisible(mAssisTv, false);
                            setVisible(mAssisSw, false);
                        } else {
                            setVisible(mStartBtn, true);
                            setVisible(mStopBtn, false);
                            setVisible(mAssisTv, true);
                            setVisible(mAssisSw, true);
                        }
                        setResultToToast("Mission Start: " + (error == null ? "Success" : error.getDescription()));
                    }
                });
                break;
            case R.id.pointing_stop_btn:
                getTapFlyMissionOperator().stopMission(new CompletionCallback() {
                    @Override
                    public void onResult(DJIError error) {
                        setResultToToast("Mission Stop: " + (error == null ? "Success" : error.getDescription()));
                    }
                });
                break;

            default:
                break;
            }
        } else {
            setResultToToast("Mission manager is null");
        }
    }

}
Reply
Replies
wlm64
What drone are you using?
2017-8-11 13:26
wlm64
I may be missing something, but It looks like you never properly initiated your getTapFlyMissionOperator().

In onCreate(), you have initUI, which says if getTapFlyMissionOperator() is already not null, then do something onStopTrackingTouch. Also, in addListener() you add listener if getTapFlyMissionOperator() is already not null, but when would it not be null?

I think you just need to add getTapFlyMissionOperator() in onCreate()
2017-8-11 13:42
Jeanlim96
wlm64 Posted at 2017-8-11 13:42
I may be missing something, but It looks like you never properly initiated your getTapFlyMissionOper ...

ahh yeah I get what you are saying. the condition I had for getTapFlyMissionOperator() is superfluous. I'm still unable to start the tapfly mission successfully though. Is there a constructor method for tapfly? I cant seem to find it in the documentation.
2017-8-14 11:47
DJI SDK Support
I would also stick some codes here.

public class TapFlyTestingActivity extends DemoBaseActivity implements View.OnClickListener, FlightControllerState.Callback {
    private TapFlyMission tapFlyMissionData;
    private TextView stateContentView;
    private TextView debugView;
    private int i = 0;

    private PopupNumberPicker mPopupNumberPicker;
    private WeakReference<FlightController> flightController;

    private TapFlyMissionOperator getTapFlyOperator() {
        return DJISDKManager.getInstance().getMissionControl().getTapFlyMissionOperator();
    }

    public void initAircraft() {
        if (DJIDemoApplication.getProductInstance() == null) {
            showToast(getString(R.string.gimbal_disconnected));
        } else {
            Aircraft mAircraft = (Aircraft) DJIDemoApplication.getProductInstance();
            if (null != mAircraft.getFlightController()) {
                flightController = new WeakReference<FlightController>(mAircraft.getFlightController());
                mAircraft.getFlightController().setStateCallback(this);
            }
        }
    }

    private void unInitAircraft() {
        if (flightController != null && flightController.get() != null) {
            flightController.get().setStateCallback(null);
        }
    }

    @Override
    protected void onDestroy() {
        unInitAircraft();
        super.onDestroy();
        tapFlyMissionData = null;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setContentView(R.layout.activity_tapfly_abstraction);
        super.onCreate(savedInstanceState);
        initAircraft();
        initTapFlyMissionData(TapFlyMode.FORWARD);
        init();
        getTapFlyOperator().addListener(new TapFlyMissionOperatorListener() {
            @Override
            public void onUpdate(@Nullable final TapFlyMissionEvent aggregation) {
                String errorInformation = "Error: " + (aggregation.getError() == null ? "null" : aggregation.getError().getDescription()) + "\n";
                String result = "";
                if (aggregation.getProgressState() != null) {
                    TapFlyExecutionState progressState = aggregation.getProgressState();
                    result = "Heading: " + progressState.getRelativeHeading() + "\n"
                            + "PointX: " + progressState.getImageLocation().x + "\n"
                            + "PointY: " + progressState.getImageLocation().y + "\n"
                            + "BypassDirection: " + progressState.getBypassDirection().name() + "\n"
                            + "VectorX: " + progressState.getDirection().getX() + "\n"
                            + "VectorY: " + progressState.getDirection().getY() + "\n"
                            + "VectorZ: " + progressState.getDirection().getZ() + "\n";
                }
                final String progressStateResult = errorInformation + result;
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        String currentState = aggregation.getCurrentState() == null ? "null" : aggregation.getCurrentState().getName();
                        String previousState = aggregation.getCurrentState() == null ? "null" : aggregation.getPreviousState().getName();
                        stateContentView.setText(i++ + "\n" + "CurrentState: " + currentState+ "\n"
                                + "PreviousState: " + previousState + "\n"
                                + progressStateResult);
                    }
                });
            }
        });

    }
    public void onUpdate(@NonNull FlightControllerState state) {
        StringBuilder result = new StringBuilder().append(" ");
        StringBuilder exceptionResult = new StringBuilder().append(" ");
        List<DJIError> pointErrors = getDJIError(DataEyeGetPushException.getInstance());
        for (DJIError error : pointErrors) {
            result.append("Exception: ").append(error.getDescription()).append("\n");
        }

        List<DJIError> exceptionErrors = getPrepareErrorList(DataEyeGetPushPointState.getInstance());
        for (DJIError error : exceptionErrors) {
            exceptionResult.append("PointError: ").append(error.getDescription()).append("\n");
        }
        final String[] output = new String[] {result.toString(), exceptionResult.toString()};
        handler.post(new Runnable() {
            @Override
            public void run() {
                debugView.setText(DataOsdGetPushCommon.getInstance().getFlycState().name() + "\n" +
                                      DataEyeGetPushPointState.getInstance().getTragetMode().name() + "\n" +
                                      DataEyeGetPushPointState.getInstance().isPaused() + "\n" +
                                      output[0] + output[1]);
            }
        });
    }

    private void init() {
        setupOnclickListener(R.id.current_state, R.id.setup_environment, R.id.set_speed,
                                R.id.set_avoidance, R.id.set_tapfly_mode, R.id.start_mission,
                                R.id.stop_mission, R.id.start_simulator, R.id.stop_simulator,
                                R.id.take_off, R.id.landing);

        stateContentView = (TextView) findViewById(R.id.tapfly__mission_tv);
        debugView = (TextView) findViewById(R.id.download_tapfly__mission_tv);
    }

    private void initTapFlyMissionData(TapFlyMode tapFlyMode) {
        tapFlyMissionData = new TapFlyMission();
        tapFlyMissionData.target = new PointF(0.5f, 0.5f);
        tapFlyMissionData.isHorizontalObstacleAvoidanceEnabled = true;
        tapFlyMissionData.speed = 1.0f;
        tapFlyMissionData.tapFlyMode = tapFlyMode;
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.current_state:
                break;

            case R.id.setup_environment:
                setupEnvironment();
                break;

            case R.id.set_speed:
                setSpeed();
                break;

            case R.id.set_avoidance:
                setHorizontalAvoidance();
                break;

            case R.id.set_tapfly_mode:
                setTapFlyMode();
                break;

            case R.id.start_mission:
                startMission();
                break;

            case R.id.stop_mission:
                stopMission();
                break;

            case R.id.start_simulator:
                startSimulator();
                break;

            case R.id.stop_simulator:
                stopSimulator();
                break;

            case R.id.take_off:
                takeOff();
                break;

            case R.id.landing:
                landing();
                break;
        }
    }

    private void setupEnvironment() {
        getTapFlyOperator().setupEnvironment(new CommonCallbacks.CompletionCallback() {
            @Override
            public void onResult(DJIError error) {
                showToast(error == null ? "Succeed" : error.getDescription());
            }
        });
    }

    private void setupOnclickListener(int... ids) {
        for (int id : ids) {
            findViewById(id).setOnClickListener(this);
        }
    }

    private void setSpeed() {
        ArrayList<String> speedValues = new ArrayList<>();
        for (int i = 1; i < 11; i ++) {
            speedValues.add(i + "");
        }
        mPopupNumberPicker = new PopupNumberPicker(this, speedValues, new PickerValueChangeListener() {

            @Override
            public void onValueChange(int pos1, int pos2) {
                mPopupNumberPicker.dismiss();
                mPopupNumberPicker = null;
                getTapFlyOperator().setAutoFlightSpeed(1.0f * (pos1 + 1), new CommonCallbacks.CompletionCallback() {
                    @Override
                    public void onResult(DJIError error) {
                        showToast(error == null ? "Succeed!" : error.getDescription());
                    }
                });
            }
        }, 250, 200, 0);
        mPopupNumberPicker.showAtLocation(findViewById(R.id.main_content_view), Gravity.CENTER, 0, 0);
    }

    private void setHorizontalAvoidance() {
        ArrayList<String> list = new ArrayList<String>();
        list.add("True");
        list.add("False");
        mPopupNumberPicker = new PopupNumberPicker(this, list, new PickerValueChangeListener() {

            @Override
            public void onValueChange(int pos1, int pos2) {
                mPopupNumberPicker.dismiss();
                mPopupNumberPicker = null;
                tapFlyMissionData.isHorizontalObstacleAvoidanceEnabled = (pos1 == 0);
            }
        }, 250, 200, 0);
        mPopupNumberPicker.showAtLocation(findViewById(R.id.main_content_view), Gravity.CENTER, 0, 0);
    }

    private void setTapFlyMode() {
        final ArrayList<String> speedValues = new ArrayList<>();
        for (int i = 0; i < 3; i ++) {
            speedValues.add(TapFlyMode.find(i).name());
        }
        mPopupNumberPicker = new PopupNumberPicker(this, speedValues, new PickerValueChangeListener() {

            @Override
            public void onValueChange(int pos1, int pos2) {
                initTapFlyMissionData(TapFlyMode.values()[pos1]);
                mPopupNumberPicker.dismiss();
                mPopupNumberPicker = null;
            }
        }, 250, 200, 0);
        mPopupNumberPicker.showAtLocation(findViewById(R.id.main_content_view), Gravity.CENTER, 0, 0);
    }

    private void startMission() {
        getTapFlyOperator().startMission(tapFlyMissionData, new CommonCallbacks.CompletionCallback() {
            @Override
            public void onResult(DJIError error) {
                showToast(error == null ? "Succeed" : error.getDescription());
            }
        });
    }

    private void stopMission() {
        getTapFlyOperator().stopMission(new CommonCallbacks.CompletionCallback() {
            @Override
            public void onResult(DJIError error) {
                showToast(error == null ? "Succeed" : error.getDescription());
            }
        });
    }

    private void startSimulator() {
        ((Aircraft)DJIDemoApplication.getProductInstance()).getFlightController().getSimulator().start(InitializationData.createInstance(new LocationCoordinate2D(23.2414, 113.1313),
                150,
                20), new CommonCallbacks.CompletionCallback() {
            @Override
            public void onResult(DJIError error) {
                showToast(error == null ? "Success" : error.getDescription());
            }
        });
    }

    private void stopSimulator() {
        ((Aircraft)DJIDemoApplication.getProductInstance()).getFlightController().getSimulator().stop(new CommonCallbacks.CompletionCallback() {
            @Override
            public void onResult(DJIError error) {
                showToast(error == null ? "Success" : error.getDescription());
            }
        });
    }

    private void takeOff() {
        ((Aircraft)DJIDemoApplication.getProductInstance()).getFlightController().startTakeoff(null);
    }

    private void landing() {
        ((Aircraft)DJIDemoApplication.getProductInstance()).getFlightController().startLanding(null);
    }
2017-8-14 16:12
Jeanlim96
DJI SDK Support Posted at 2017-8-14 16:12
I would also stick some codes here.

public class TapFlyTestingActivity extends DemoBaseActivity im ...

Hi I've added the codes into my code but I'm still facing problems executing the tapfly mission on DJI assistant. The DJIerror that appears consistently is 'Execution of this process has timed out'. Could it be because of the existence of obstacles picked up by the drone (but not present in the simulator)?  According to the mission state updates, the mission state goes from idle to execution starting and then back to idle.
2017-8-18 17:36
You need to log in before you can reply Login | Register now

Quick Reply Back to top Back to list
Quick Reply Back to top Back to list