public static void gotoWaypoint(MavLinkDrone drone, int waypoint, ICommandListener listener) {
   if (drone == null) return;
   if (waypoint < 0) {
     postErrorEvent(CommandExecutionError.COMMAND_FAILED, listener);
     return;
   }
   MavLinkDoCmds.gotoWaypoint(drone, waypoint, listener);
 }
  public static void stopVideoStream(
      Drone drone, String appId, String videoTag, ICommandListener listener) {
    if (!(drone instanceof GenericMavLinkDrone)) {
      postErrorEvent(CommandExecutionError.COMMAND_UNSUPPORTED, listener);
      return;
    }

    final GenericMavLinkDrone mavLinkDrone = (GenericMavLinkDrone) drone;
    mavLinkDrone.stopVideoStream(appId, videoTag, listener);
  }
  public static void startMission(
      final MavLinkDrone drone,
      final boolean forceModeChange,
      final boolean forceArm,
      final ICommandListener listener) {
    if (drone == null) {
      return;
    }

    final Runnable sendCommandRunnable =
        new Runnable() {
          @Override
          public void run() {
            msg_command_long msg = new msg_command_long();
            msg.target_system = drone.getSysid();
            msg.target_component = drone.getCompid();
            msg.command = MAV_CMD.MAV_CMD_MISSION_START;

            drone.getMavClient().sendMavMessage(msg, listener);
          }
        };

    final Runnable modeCheckRunnable =
        new Runnable() {
          @Override
          public void run() {
            if (drone.getState().getMode() != ApmModes.ROTOR_AUTO) {
              if (forceModeChange) {
                changeVehicleMode(
                    drone,
                    VehicleMode.COPTER_AUTO,
                    new AbstractCommandListener() {
                      @Override
                      public void onSuccess() {
                        sendCommandRunnable.run();
                      }

                      @Override
                      public void onError(int executionError) {
                        postErrorEvent(executionError, listener);
                      }

                      @Override
                      public void onTimeout() {
                        postTimeoutEvent(listener);
                      }
                    });
              } else {
                postErrorEvent(CommandExecutionError.COMMAND_FAILED, listener);
              }
              return;
            } else {
              sendCommandRunnable.run();
            }
          }
        };

    if (!drone.getState().isArmed()) {
      if (forceArm) {
        arm(
            drone,
            true,
            new AbstractCommandListener() {
              @Override
              public void onSuccess() {
                modeCheckRunnable.run();
              }

              @Override
              public void onError(int executionError) {
                postErrorEvent(executionError, listener);
              }

              @Override
              public void onTimeout() {
                postTimeoutEvent(listener);
              }
            });
      } else {
        postErrorEvent(CommandExecutionError.COMMAND_FAILED, listener);
      }
      return;
    }

    modeCheckRunnable.run();
  }