目录

文章目录

  • 目录
  • 摘要
  • 1.发送逻辑代码
  • 2.设置无人机的飞行模式理解发送过程

摘要


本周主要记录打造自己的HelloDrone 无人机APP过程《3》–如何实现APP给飞控发送数据相关逻辑,欢迎批评指正!!!


1.发送逻辑代码

    /*** 打开设备,执行mManagerTask任务* @param extras*/protected void onConnectionOpened(Bundle extras) {if (mConnectionStatus.compareAndSet(MAVLINK_CONNECTING, MAVLINK_CONNECTED)) {extrasHolder.set(extras);mLogger.logInfo(TAG, "Starting manager thread.");Log.i("lxw"," mManagerTask主要处理mavlink信息");mTaskThread = new Thread(mManagerTask, "MavLinkConnection-Manager Thread");mTaskThread.start();}}

这里我们重点看: mTaskThread = new Thread(mManagerTask, “MavLinkConnection-Manager Thread”);创建了一个任务管理线程。并通过mTaskThread.start()启动创建的线程

    /*** 管理消息的接收和发送。主要处理mavlink信息* Manages the receiving and sending of messages.*/private final Runnable mManagerTask = new Runnable() {@Overridepublic void run() {Thread sendingThread = null;Thread loggingThread = null;try {final long connectionTime = System.currentTimeMillis();mConnectionTime.set(connectionTime);reportConnect(connectionTime);// Launch the 'Sending' threadmLogger.logInfo(TAG, "Starting sender thread.");Log.i("lxw"," Starting new thread.");sendingThread = new Thread(mSendingTask, "MavLinkConnection-Sending Thread");sendingThread.start();//Launch the 'Logging' threadmLogger.logInfo(TAG, "Starting logging thread.");Log.i("lxw"," Starting sender thread.");loggingThread = new Thread(mLoggingTask, "MavLinkConnection-Logging Thread");loggingThread.start();//协议解析final Parser parser = new Parser();//com.MAVLink.ParserLog.i("lxw"," parser:"+parser);//服务解析状态parser.stats.resetStats();//创建解析数据数组final byte[] readBuffer = new byte[READ_BUFFER_SIZE];while (mConnectionStatus.get() == MAVLINK_CONNECTED){//读取bufferSizeint bufferSize = readDataBlock(readBuffer);//bufferSize=Log.i("lxw"," bufferSize:"+bufferSize);handleData(parser, bufferSize, readBuffer);}} catch (IOException e) {// Ignore errors while shutting downif (mConnectionStatus.get() != MAVLINK_DISCONNECTED) {reportIOException(e);mLogger.logErr(TAG, e);}} finally {if (sendingThread != null && sendingThread.isAlive()) {sendingThread.interrupt();}if (loggingThread != null && loggingThread.isAlive()) {loggingThread.interrupt();}disconnect();mLogger.logInfo(TAG, "Exiting manager thread.");}}/*** 开始进行数据处理* @param parser* @param bufferSize* @param buffer*/private void handleData(Parser parser, int bufferSize, byte[] buffer) {if (bufferSize < 1) {return;}for (int i = 0; i < bufferSize; i++){//解析包MAVLinkPacket receivedPacket = parser.mavlink_parse_char(buffer[i] & 0x00ff);if (receivedPacket != null){queueToLog(receivedPacket);Log.i("lxw"," 开始报告解析:");reportReceivedPacket(receivedPacket);}}}};

对于接收的函数我们不在讲解,在第二节打造自己的HelloDrone 无人机APP过程《2》已经讲述,本节主要分析发送数据到外界。


从上面代码可以看出,在mManagerTask线程中又定义子线程

            //定义发送线程Thread sendingThread = null;//定义log线程Thread loggingThread = null;

重点启动发送线程代码如下:

                //启动“发送”线程---- Launch the 'Sending' threadmLogger.logInfo(TAG, "Starting sender thread.");Log.i("lxw"," Starting new thread.");sendingThread = new Thread(mSendingTask, "MavLinkConnection-Sending Thread");sendingThread.start();

创建发送线程mSendingTask,通过sendingThread.start()启动线程。

    /*** 阻塞,直到有数据包要发送,然后发送它们。* Blocks until there's packet(s) to send, then dispatch them.*/private final Runnable mSendingTask = new Runnable() {@Overridepublic void run() {try {//当usb连接上时while (mConnectionStatus.get() == MAVLINK_CONNECTED) {byte[] buffer = mPacketsToSend.take();try {//发送数据sendBuffer(buffer);queueToLog(buffer);} catch (IOException e) {reportIOException(e);mLogger.logErr(TAG, e);}}} catch (InterruptedException e) {mLogger.logVerbose(TAG, e.getMessage());} finally {disconnect();}}};

2.设置无人机的飞行模式理解发送过程

首先设置UI界面,采用下拉列表显示模式

在主activity中设置点击事件

这里我们重点看下执行模式选择

其中Spinner提供了从一个数据集合中快速选择一项值的办法。默认情况下Spinner显示的是当前选择的值,点击Spinner会弹出一个包含所有可选值的dropdown菜单,从该菜单中可以为Spinner选择一个新值。


默认飞机上电会自动读取当前的飞行模式,具体实现后面讲解,我们先看下模式选择


                //执行飞行器模式选择onFlightModeSelected(view);
    /*** 执行模式选择** @param view*/public void onFlightModeSelected(View view) {//获取无人机的模式VehicleMode vehicleMode = (VehicleMode) this.modeSelector.getSelectedItem();//获取并设置模式VehicleApi.getApi(this.drone).setVehicleMode(vehicleMode, new AbstractCommandListener() {@Overridepublic void onSuccess(){//执行成功alertUser("Vehicle mode change successful.");}@Overridepublic void onError(int executionError) {//模式更改失败alertUser("Vehicle mode change failed: " + executionError);}@Overridepublic void onTimeout() {//模式更改超时alertUser("Vehicle mode change timed out.");}});}

其中类enum VehicleMode的实现如下代码所示。

package com.o3dr.services.android.lib.drone.property;import android.os.Parcel;import java.util.ArrayList;
import java.util.List;/*** Created by fhuya on 10/28/14.*/
public enum VehicleMode implements DroneAttribute {//固定翼模式设置PLANE_MANUAL(0, Type.TYPE_PLANE, "Manual"),PLANE_CIRCLE(1, Type.TYPE_PLANE, "Circle"),PLANE_STABILIZE(2, Type.TYPE_PLANE, "Stabilize"),PLANE_TRAINING(3, Type.TYPE_PLANE, "Training"),PLANE_ACRO(4, Type.TYPE_PLANE, "Acro"),PLANE_FLY_BY_WIRE_A(5, Type.TYPE_PLANE, "FBW A"),PLANE_FLY_BY_WIRE_B(6, Type.TYPE_PLANE, "FBW B"),PLANE_CRUISE(7, Type.TYPE_PLANE, "Cruise"),PLANE_AUTOTUNE(8, Type.TYPE_PLANE, "Autotune"),PLANE_AUTO(10, Type.TYPE_PLANE, "Auto"),PLANE_RTL(11, Type.TYPE_PLANE, "RTL"),PLANE_LOITER(12, Type.TYPE_PLANE, "Loiter"),PLANE_GUIDED(15, Type.TYPE_PLANE, "Guided"),//多旋翼模式设置COPTER_STABILIZE(0, Type.TYPE_COPTER, "Stabilize"), //姿态模式COPTER_ACRO(1, Type.TYPE_COPTER, "Acro"),          //速率模式COPTER_ALT_HOLD(2, Type.TYPE_COPTER, "Alt Hold"),  //定高模式COPTER_AUTO(3, Type.TYPE_COPTER, "Auto"),          //自动模式COPTER_GUIDED(4, Type.TYPE_COPTER, "Guided"),      //引导模式COPTER_LOITER(5, Type.TYPE_COPTER, "Loiter"),      //悬停模式COPTER_RTL(6, Type.TYPE_COPTER, "RTL"),            //返航模式COPTER_CIRCLE(7, Type.TYPE_COPTER, "Circle"),      //绕圈模式COPTER_LAND(9, Type.TYPE_COPTER, "Land"),          //着落模式COPTER_DRIFT(11, Type.TYPE_COPTER, "Drift"),       //漂移模式COPTER_SPORT(13, Type.TYPE_COPTER, "Sport"),       //运动模式COPTER_FLIP(14, Type.TYPE_COPTER, "Flip"),         //斜坡模式COPTER_AUTOTUNE(15, Type.TYPE_COPTER, "Autotune"), //自动调参模式COPTER_POSHOLD(16, Type.TYPE_COPTER, "PosHold"),   //位置保持模式COPTER_BRAKE(17,Type.TYPE_COPTER,"Brake"),         //刹车模式//无人车模式设置ROVER_MANUAL(0, Type.TYPE_ROVER, "Manual"),ROVER_LEARNING(2, Type.TYPE_ROVER, "Learning"),ROVER_STEERING(3, Type.TYPE_ROVER, "Steering"),ROVER_HOLD(4, Type.TYPE_ROVER, "Hold"),ROVER_AUTO(10, Type.TYPE_ROVER, "Auto"),ROVER_RTL(11, Type.TYPE_ROVER, "RTL"),ROVER_GUIDED(15, Type.TYPE_ROVER, "Guided"),ROVER_INITIALIZING(16, Type.TYPE_ROVER, "Initializing"),UNKNOWN(-1, Type.TYPE_UNKNOWN, "Unknown");private final int mode;private final int droneType;private final String label;VehicleMode(int mode, int droneType, String label){this.mode = mode;this.droneType = droneType;this.label = label;}public int getMode() {return mode;}public int getDroneType() {return droneType;}public String getLabel() {return label;}@Overridepublic String toString(){return getLabel();}@Overridepublic int describeContents(){return 0;}@Overridepublic void writeToParcel(final Parcel dest, final int flags){dest.writeString(name());}public static final Creator<VehicleMode> CREATOR = new Creator<VehicleMode>() {@Overridepublic VehicleMode createFromParcel(Parcel source) {return VehicleMode.valueOf(source.readString());}@Overridepublic VehicleMode[] newArray(int size) {return new VehicleMode[size];}};public static List<VehicleMode> getVehicleModePerDroneType(int droneType){VehicleMode[] availableModes = VehicleMode.values();final List<VehicleMode> vehicleModes = new ArrayList<VehicleMode>(availableModes.length);for(VehicleMode vehicleMode: availableModes){if(vehicleMode.getDroneType() == droneType)vehicleModes.add(vehicleMode);}return vehicleModes;}
}

对于我们多旋翼的使用模式主要是下面模式:

上面代码主要有两行比较重要:
1.获取当前模式:

 VehicleMode vehicleMode = (VehicleMode) this.modeSelector.getSelectedItem();

2.设置当前模式到飞控,采用匿名内部类实现


我们先不关注函数的参数,重点看下函数实现

/*** 更改连接的无人机的车辆模式。* Change the vehicle mode for the connected drone.** @param newMode  新车模式---new vehicle mode.* @param listener 注册回调以接收命令执行状态的更新。Register a callback to receive update of the command execution state.*/public void setVehicleMode(VehicleMode newMode, AbstractCommandListener listener) {//新建参数Bundle params = new Bundle();//参数输出设置,一会外界会采用键值方式获取params.putParcelable(EXTRA_VEHICLE_MODE, newMode);//执行设置命令drone.performAsyncActionOnDroneThread(new Action(ACTION_SET_VEHICLE_MODE, params), listener);}

比较重要的函数有两个:

1.核心代码

 params.putParcelable(EXTRA_VEHICLE_MODE, newMode);

2.核心代码

drone.performAsyncActionOnDroneThread(new Action(ACTION_SET_VEHICLE_MODE, params), listener);

我们先看第一处代码:

设置的新模式,一会会传递出去:
1.ArduPilot.java

2.GenericMavLinkDrone.java处代码

上面具体如何使用,后续再看,先分析重点内容。

drone.performAsyncActionOnDroneThread(new Action(ACTION_SET_VEHICLE_MODE, params), listener);

上面函数传递两个参数:new Action(ACTION_SET_VEHICLE_MODE, params)和listener

    /***执行异步行为*/public boolean performAsyncActionOnDroneThread(Action action, AbstractCommandListener listener) {//执行异步行为处理return performAsyncActionOnHandler(action, this.handler, listener);}
    /***执行异步行为*/public boolean performAsyncActionOnHandler(Action action, Handler handler, AbstractCommandListener listener) {boolean value=false;Log.i("lxw","performAsyncActionOnHandler");final IDroneApi droneApi = droneApiRef.get();//org.droidplanner.services.android.impl.api.DroneApiLog.i("lxw","droneApi:"+droneApi);value=isStarted(droneApi);Log.i("lxw","isStarted value:"+value);if (value){try {//执行行为Log.i("lxw","executeAsyncAction:");droneApi.executeAsyncAction(action, wrapListener(handler, listener));return true;} catch (RemoteException e){Log.i("lxw","执行 RemoteException");Toast.makeText(getContext(), "异步执行2", Toast.LENGTH_LONG).show();handleRemoteException(e);}}Log.i("lxw","disconnect7");return false;}

重点分析这个函数:

 droneApi.executeAsyncAction(action, wrapListener(handler, listener));
/*** 执行代码* @param action Action to perform.* @param listener Register a callback to be invoken when the action is executed.* @throws RemoteException*/@Overridepublic void executeAsyncAction(Action action, ICommandListener listener) throws RemoteException {Log.i("lxw","执行DroneApi中的executeAsyncAction");Log.i("zqj","执行DroneApi中的executeAsyncAction");//执行异步操作行为executeAction(action, listener);}
    @Override/*** 执行行为*/public voidexecuteAction(Action action, ICommandListener listener) throws RemoteException {//com.o3dr.services.android.lib.model.action.ActionLog.i("lxw","executeAction action:"+action);if (action == null){Log.i("zqj","executeAction action:"+action);Log.i("lxw","action null:");return;}String type = action.getType();//type com.o3dr.services.android.action.CONNECTLog.i("lxw","type:"+type);//type:com.o3dr.services.android.action.SET_VEHICLE_MODELog.i("zqj","type:"+type);if (type == null){Log.i("lxw","type null:");return;}Bundle data = action.getData();Log.i("lxw","Bundle data:"+data);//Bundle data:Bundle[{extra_vehicle_mode=Alt Hold}]Log.i("zqj","Bundle data:"+data);if (data != null) {Log.i("lxw","data not null:");data.setClassLoader(context.getClassLoader());}//获取设备Drone drone = getDrone();Log.i("lxw","drone1:"+drone);Log.i("lxw","mytype:"+type);Log.i("zqj","mytype:"+type);//mytype:com.o3dr.services.android.action.SET_VEHICLE_MODEswitch (type) {// CONNECTION ACTIONScase ConnectionActions.ACTION_CONNECT:ConnectionParameter parameter = data.getParcelable(ConnectionActions.EXTRA_CONNECT_PARAMETER);Log.i("lxw","ConnectionActions:");//进行连接connect(parameter);break;case ConnectionActions.ACTION_DISCONNECT:disconnect();break;// CAMERA ACTIONScase CameraActions.ACTION_START_VIDEO_STREAM: {Surface videoSurface = data.getParcelable(CameraActions.EXTRA_VIDEO_DISPLAY);String videoTag = data.getString(CameraActions.EXTRA_VIDEO_TAG, "");Bundle videoProps = data.getBundle(CameraActions.EXTRA_VIDEO_PROPERTIES);if (videoProps == null) {//Only case where it's null is when interacting with a deprecated client version.//In this case, we assume that the client is attempting to start a solo stream, since that's//the only api that was exposed.videoProps = new Bundle();videoProps.putInt(CameraActions.EXTRA_VIDEO_PROPS_UDP_PORT, VideoManager.ARTOO_UDP_PORT);}CommonApiUtils.startVideoStream(drone, videoProps, ownerId, videoTag, videoSurface, listener);break;}case ExperimentalActions.ACTION_START_VIDEO_STREAM_FOR_OBSERVER: {String videoTag = data.getString(CameraActions.EXTRA_VIDEO_TAG, "");CommonApiUtils.startVideoStreamForObserver(drone, ownerId, videoTag, listener);break;}case CameraActions.ACTION_STOP_VIDEO_STREAM: {String videoTag = data.getString(CameraActions.EXTRA_VIDEO_TAG, "");CommonApiUtils.stopVideoStream(drone, ownerId, videoTag, listener);break;}case ExperimentalActions.ACTION_STOP_VIDEO_STREAM_FOR_OBSERVER: {String videoTag = data.getString(CameraActions.EXTRA_VIDEO_TAG, "");CommonApiUtils.stopVideoStreamForObserver(drone, ownerId, videoTag, listener);break;}// MISSION ACTIONScase MissionActions.ACTION_BUILD_COMPLEX_MISSION_ITEM:if (drone instanceof MavLinkDrone || drone == null) {CommonApiUtils.buildComplexMissionItem((MavLinkDrone) drone, data);} else {CommonApiUtils.postErrorEvent(CommandExecutionError.COMMAND_UNSUPPORTED, listener);}break;case MissionActions.ACTION_SAVE_MISSION: {Mission mission = data.getParcelable(MissionActions.EXTRA_MISSION);Uri saveUri = data.getParcelable(MissionActions.EXTRA_SAVE_MISSION_URI);if (saveUri == null) {CommonApiUtils.postErrorEvent(CommandExecutionError.COMMAND_FAILED, listener);} else {MissionUtils.saveMission(context, mission, saveUri, listener);}break;}case MissionActions.ACTION_LOAD_MISSION: {Uri loadUri = data.getParcelable(MissionActions.EXTRA_LOAD_MISSION_URI);boolean setMission = data.getBoolean(MissionActions.EXTRA_SET_LOADED_MISSION, false);if (loadUri != null) {Mission mission = MissionUtils.loadMission(context, loadUri);if(mission != null){// Going back to the caller.data.putParcelable(MissionActions.EXTRA_MISSION, mission);if(setMission){Bundle params = new Bundle();params.putParcelable(EXTRA_MISSION, mission);params.putBoolean(EXTRA_PUSH_TO_DRONE, false);executeAction(new Action(ACTION_SET_MISSION, params), listener);}}}break;}default:if (droneMgr != null){Log.i("zqj","droneMgr:"+droneMgr);droneMgr.executeAsyncAction(clientInfo, action, listener);} else {Log.i("zqj","droneMgr1:"+droneMgr);CommonApiUtils.postErrorEvent(CommandExecutionError.COMMAND_FAILED, listener);}break;}}

打印可以监视代码执行顺序

    /*** 执行异步行为*/public boolean executeAsyncAction(DroneApi.ClientInfo clientInfo, Action action, ICommandListener listener) {String type = action.getType();Bundle data = action.getData();Log.i("lxw","DT4");Log.i("zqj","DT4");Log.i("zqj","type:"+type);switch (type) {case ControlActions.ACTION_ENABLE_MANUAL_CONTROL:data.putString(EXTRA_CLIENT_APP_ID, clientInfo.appId);break;}Log.i("zqj","type1:"+type);return executeAsyncAction(action, listener);}

开始分析核心代码:return executeAsyncAction(action, listener);

    protected boolean executeAsyncAction(Action action, ICommandListener listener) {String type = action.getType();Log.i("zqj","type2:"+type);switch (type) {//***************** CONTROL ACTIONS *****************//case ControlActions.ACTION_ENABLE_MANUAL_CONTROL:if (drone != null) {drone.executeAsyncAction(action, listener);} else {CommonApiUtils.postErrorEvent(CommandExecutionError.COMMAND_FAILED, listener);}return true;default:if (drone != null) {Log.i("zqj","drone:"+drone);return drone.executeAsyncAction(action, listener);} else {Log.i("zqj","listener:"+listener);CommonApiUtils.postErrorEvent(CommandExecutionError.COMMAND_FAILED, listener);return true;}}}
/*** 首先执行的方法* @param action* @param listener* @return*/@Overridepublic boolean executeAsyncAction(Action action, final ICommandListener listener) {//获取类型String type = action.getType();//获取数据Bundle data = action.getData();if (data == null) {data = new Bundle();}Log.i("zqj"," Ardupilot mytype:"+type);switch (type) {//执行任务行为----- MISSION ACTIONScase MissionActions.ACTION_LOAD_WAYPOINTS:CommonApiUtils.loadWaypoints(this);return true;//设置任务行为case MissionActions.ACTION_SET_MISSION:data.setClassLoader(com.o3dr.services.android.lib.drone.mission.Mission.class.getClassLoader());com.o3dr.services.android.lib.drone.mission.Mission mission = data.getParcelable(MissionActions.EXTRA_MISSION);boolean pushToDrone = data.getBoolean(MissionActions.EXTRA_PUSH_TO_DRONE);CommonApiUtils.setMission(this, mission, pushToDrone);return true;//开始任务行为case MissionActions.ACTION_START_MISSION:boolean forceModeChange = data.getBoolean(MissionActions.EXTRA_FORCE_MODE_CHANGE);boolean forceArm = data.getBoolean(MissionActions.EXTRA_FORCE_ARM);CommonApiUtils.startMission(this, forceModeChange, forceArm, listener);return true;//实验动作---- EXPERIMENTAL ACTIONScase ExperimentalActions.ACTION_EPM_COMMAND:boolean release = data.getBoolean(ExperimentalActions.EXTRA_EPM_RELEASE);CommonApiUtils.epmCommand(this, release, listener);return true;// 触发照相行为case ExperimentalActions.ACTION_TRIGGER_CAMERA:CommonApiUtils.triggerCamera(this);return true;// 做任务case ExperimentalActions.ACTION_SET_ROI:LatLongAlt roi = data.getParcelable(ExperimentalActions.EXTRA_SET_ROI_LAT_LONG_ALT);if (roi != null) {MavLinkDoCmds.setROI(this, roi, listener);}return true;// ACTION_SET_RELAYcase ExperimentalActions.ACTION_SET_RELAY:int relayNumber = data.getInt(ExperimentalActions.EXTRA_RELAY_NUMBER);boolean isOn = data.getBoolean(ExperimentalActions.EXTRA_IS_RELAY_ON);MavLinkDoCmds.setRelay(this, relayNumber, isOn, listener);return true;case ExperimentalActions.ACTION_SET_SERVO:int channel = data.getInt(ExperimentalActions.EXTRA_SERVO_CHANNEL);int pwm = data.getInt(ExperimentalActions.EXTRA_SERVO_PWM);MavLinkDoCmds.setServo(this, channel, pwm, listener);return true;//控制行为--- CONTROL ACTIONScase ControlActions.ACTION_SEND_GUIDED_POINT: {data.setClassLoader(LatLong.class.getClassLoader());boolean force = data.getBoolean(ControlActions.EXTRA_FORCE_GUIDED_POINT);LatLong guidedPoint = data.getParcelable(ControlActions.EXTRA_GUIDED_POINT);CommonApiUtils.sendGuidedPoint(this, guidedPoint, force, listener);return true;}//ACTION_LOOK_AT_TARGETcase ControlActions.ACTION_LOOK_AT_TARGET:boolean force = data.getBoolean(ControlActions.EXTRA_FORCE_GUIDED_POINT);LatLongAlt lookAtTarget = data.getParcelable(ControlActions.EXTRA_LOOK_AT_TARGET);CommonApiUtils.sendLookAtTarget(this, lookAtTarget, force, listener);return true;//设置引导高度case ControlActions.ACTION_SET_GUIDED_ALTITUDE:double guidedAltitude = data.getDouble(ControlActions.EXTRA_ALTITUDE);CommonApiUtils.setGuidedAltitude(this, guidedAltitude);return true;//执行参数行为PARAMETER ACTIONScase ParameterActions.ACTION_REFRESH_PARAMETERS:CommonApiUtils.refreshParameters(this);return true;//写参数行为case ParameterActions.ACTION_WRITE_PARAMETERS:data.setClassLoader(com.o3dr.services.android.lib.drone.property.Parameters.class.getClassLoader());com.o3dr.services.android.lib.drone.property.Parameters parameters = data.getParcelable(ParameterActions.EXTRA_PARAMETERS);CommonApiUtils.writeParameters(this, parameters);return true;//设置HOME点行为---- DRONE STATE ACTIONScase StateActions.ACTION_SET_VEHICLE_HOME:LatLongAlt homeLoc = data.getParcelable(StateActions.EXTRA_VEHICLE_HOME_LOCATION);if (homeLoc != null) {MavLinkDoCmds.setVehicleHome(this, homeLoc, new AbstractCommandListener() {@Overridepublic void onSuccess() {CommonApiUtils.postSuccessEvent(listener);requestHomeUpdate();}@Overridepublic void onError(int executionError) {CommonApiUtils.postErrorEvent(executionError, listener);requestHomeUpdate();}@Overridepublic void onTimeout() {CommonApiUtils.postTimeoutEvent(listener);requestHomeUpdate();}});} else {CommonApiUtils.postErrorEvent(CommandExecutionError.COMMAND_FAILED, listener);}return true;//校准行为-----CALIBRATION ACTIONScase CalibrationActions.ACTION_START_IMU_CALIBRATION:CommonApiUtils.startIMUCalibration(this, listener);return true;//IMU校准应答case CalibrationActions.ACTION_SEND_IMU_CALIBRATION_ACK:int imuAck = data.getInt(CalibrationActions.EXTRA_IMU_STEP);CommonApiUtils.sendIMUCalibrationAck(this, imuAck);return true;//地磁校准case CalibrationActions.ACTION_START_MAGNETOMETER_CALIBRATION:boolean retryOnFailure = data.getBoolean(CalibrationActions.EXTRA_RETRY_ON_FAILURE, false);boolean saveAutomatically = data.getBoolean(CalibrationActions.EXTRA_SAVE_AUTOMATICALLY, true);int startDelay = data.getInt(CalibrationActions.EXTRA_START_DELAY, 0);CommonApiUtils.startMagnetometerCalibration(this, retryOnFailure, saveAutomatically, startDelay);return true;//取消地磁校准case CalibrationActions.ACTION_CANCEL_MAGNETOMETER_CALIBRATION:CommonApiUtils.cancelMagnetometerCalibration(this);return true;//接受地磁校准case CalibrationActions.ACTION_ACCEPT_MAGNETOMETER_CALIBRATION:CommonApiUtils.acceptMagnetometerCalibration(this);return true;//************万向节动作 Gimbal ACTIONS *************//case GimbalActions.ACTION_SET_GIMBAL_ORIENTATION:float pitch = data.getFloat(GimbalActions.GIMBAL_PITCH);float roll = data.getFloat(GimbalActions.GIMBAL_ROLL);float yaw = data.getFloat(GimbalActions.GIMBAL_YAW);MavLinkDoCmds.setGimbalOrientation(this, pitch, roll, yaw, listener);return true;case GimbalActions.ACTION_RESET_GIMBAL_MOUNT_MODE:case GimbalActions.ACTION_SET_GIMBAL_MOUNT_MODE:int mountMode = data.getInt(GimbalActions.GIMBAL_MOUNT_MODE, MAV_MOUNT_MODE.MAV_MOUNT_MODE_RC_TARGETING);Timber.i("Setting gimbal mount mode: %d", mountMode);Parameter mountParam = getParameterManager().getParameter("MNT_MODE");if (mountParam == null) {msg_mount_configure msg = new msg_mount_configure();msg.target_system = getSysid();msg.target_component = getCompid();msg.mount_mode = (byte) mountMode;msg.stab_pitch = 0;msg.stab_roll = 0;msg.stab_yaw = 0;getMavClient().sendMessage(msg, listener);} else {MavLinkParameters.sendParameter(this, "MNT_MODE", 1, mountMode);}return true;default:Log.i("zqj"," 执行父类方法executeAsyncAction:");return super.executeAsyncAction(action, listener);}}

执行完上面的方法后,会调用父类的实现方法

    /*** 执行异步行为*/public boolean executeAsyncAction(Action action, ICommandListener listener) {String type = action.getType();Bundle data = action.getData();Log.i("lxw","DT3");Log.i("zqj","GenericMavlinkDrone mytype:"+type);switch (type) {//MISSION ACTIONScase MissionActions.ACTION_GENERATE_DRONIE:float bearing = CommonApiUtils.generateDronie(this);if (bearing != -1) {Bundle bundle = new Bundle(1);bundle.putFloat(AttributeEventExtra.EXTRA_MISSION_DRONIE_BEARING, bearing);notifyAttributeListener(AttributeEvent.MISSION_DRONIE_CREATED, bundle);}return true;//跳转到航点case MissionActions.ACTION_GOTO_WAYPOINT:int missionItemIndex = data.getInt(MissionActions.EXTRA_MISSION_ITEM_INDEX);CommonApiUtils.gotoWaypoint(this, missionItemIndex, listener);return true;//改变航点速度行为case MissionActions.ACTION_CHANGE_MISSION_SPEED:float missionSpeed = data.getFloat(MissionActions.EXTRA_MISSION_SPEED);MavLinkCommands.changeMissionSpeed(this, missionSpeed, listener);return true;//解锁行为---- STATE ACTIONScase StateActions.ACTION_ARM:return performArming(data, listener);//设置模式行为case StateActions.ACTION_SET_VEHICLE_MODE:Log.i("zqj","ACTION_SET_VEHICLE_MODE:");return setVehicleMode(data, listener);case StateActions.ACTION_UPDATE_VEHICLE_DATA_STREAM_RATE:return updateVehicleDataStreamRate(data, listener);//控制行为,执行起飞 CONTROL ACTIONScase ControlActions.ACTION_DO_GUIDED_TAKEOFF:return performTakeoff(data, listener);//发送刹车行为case ControlActions.ACTION_SEND_BRAKE_VEHICLE:return brakeVehicle(listener);//设置偏航控制case ControlActions.ACTION_SET_CONDITION_YAW:// Retrieve the yaw turn speed.float turnSpeed = 2; // Default turn speed.ParameterManager parameterManager = getParameterManager();if (parameterManager != null) {Parameter turnSpeedParam = parameterManager.getParameter("ACRO_YAW_P");if (turnSpeedParam != null) {turnSpeed = (float) turnSpeedParam.getValue();}}float targetAngle = data.getFloat(ControlActions.EXTRA_YAW_TARGET_ANGLE);float yawRate = data.getFloat(ControlActions.EXTRA_YAW_CHANGE_RATE);boolean isClockwise = yawRate >= 0;boolean isRelative = data.getBoolean(ControlActions.EXTRA_YAW_IS_RELATIVE);MavLinkCommands.setConditionYaw(this, targetAngle, Math.abs(yawRate) * turnSpeed, isClockwise, isRelative, listener);return true;//设置速度行为case ControlActions.ACTION_SET_VELOCITY:return setVelocity(data, listener);case ControlActions.ACTION_ENABLE_MANUAL_CONTROL:return enableManualControl(data, listener);// EXPERIMENTAL ACTIONScase ExperimentalActions.ACTION_SEND_MAVLINK_MESSAGE:data.setClassLoader(MavlinkMessageWrapper.class.getClassLoader());MavlinkMessageWrapper messageWrapper = data.getParcelable(ExperimentalActions.EXTRA_MAVLINK_MESSAGE);CommonApiUtils.sendMavlinkMessage(this, messageWrapper);return true;// INTERNAL DRONE ACTIONScase ACTION_REQUEST_HOME_UPDATE:requestHomeUpdate();return true;//**************** CAPABILITY ACTIONS **************//case CapabilityActions.ACTION_CHECK_FEATURE_SUPPORT:return checkFeatureSupport(data, listener);default:CommonApiUtils.postErrorEvent(CommandExecutionError.COMMAND_UNSUPPORTED, listener);return true;}}


这个函数执行子类的方法而不是父类的。除非在解锁模式下

    @Overrideprotected boolean setVehicleMode(Bundle data, ICommandListener listener) {Log.i("zqj"," ARDUPILOT:");data.setClassLoader(VehicleMode.class.getClassLoader());VehicleMode newMode = data.getParcelable(StateActions.EXTRA_VEHICLE_MODE);CommonApiUtils.changeVehicleMode(this, newMode, listener);Log.i("zqj"," ARDUPILOT: FINISH");return true;}

父类中也有类似的实现方法:

    protected boolean setVehicleMode(Bundle data, ICommandListener listener) {data.setClassLoader(VehicleMode.class.getClassLoader());//还记得之前提起的地方吗EXTRA_VEHICLE_MODE。在这里实现VehicleMode newMode = data.getParcelable(StateActions.EXTRA_VEHICLE_MODE);Log.i("zqj"," newMode:"+newMode);if (newMode != null) {switch (newMode) {//是不是着落模式case COPTER_LAND:MavLinkCommands.sendNavLand(this, listener);break;//返航模式case COPTER_RTL:MavLinkCommands.sendNavRTL(this, listener);break;//引导模式case COPTER_GUIDED:MavLinkCommands.sendPause(this, listener);break;//是不是自动模式case COPTER_AUTO:MavLinkCommands.startMission(this, listener);break;}}Log.i("zqj"," MODE return:");return true;}

打造自己的HelloDrone 无人机APP过程《3》相关推荐

  1. 如何打造一款出色的APP

    本文主要是讲述如何打造一款出色的APP,更多android开发技术专业知识,请登陆疯狂软件教育官网. 在这个移动互联网时代各种各样的APP层出不穷,有的APP从始至终就没有被用户接受.有的APP火爆一 ...

  2. mPaaS:全新移动开发平台,只为打造性能更优越的App

    简介: 基于移动开发现状与技术演进预判,提供移动开发强力解决方案,洞察 mPaaS 如何帮助企业有效降低技术门槛,减少研发成本,搭建更稳定.更流畅的移动 App. mPaaS 是源自于支付宝的移动开发 ...

  3. 用sockets打造自己的Android聊天app(安卓篇)

    用sockets打造自己的Android聊天app(安卓篇) 翻译自http://www.androidhive.info/2014/10/android-building-group-chat-ap ...

  4. uniapp开发app过程中集成友盟统计

    uniapp在开发app过程中,需要集成友盟统计,可参考以下流程进行配置 友盟统计官网注册并获取appkey 单独创建安卓跟ios的应用,获取到appkey(这里以安卓为例) 配置manifest.j ...

  5. vue做混合式app_Vue Cordova教程-Vue+Cordova打造跨平台可安装的混合APP视频教程(大地)...

    Vue+Cordova打造跨平台可安装的混合APP视频教程 必看说明: 目前购买此教程送Html5+Cordova+Ionic智能电视(TV)应用开发教程视频教程: 购买过Ionic的同学可以直接在( ...

  6. 又拍云沈志华:如何打造一款安全的App

    8月23日,网易易盾发起的国内首个互联网内容安全联盟在杭州成立,又拍云作为该联盟的首批成员单位出席了成立仪式.又拍云COO沈志华在成立仪式上发表了精彩的演讲,并接受了媒体专访. \\ 沈志华在演讲中详 ...

  7. 我是如何从 0 到 1 打造一款百万用户 App 的?

    各位同行好,我是「棋路-中国象棋」App 的开发者贺照云.我喜欢中国象棋,一直希望在象棋传统文化的传承中做点什么. 早在 2007 年 Android 刚刚提供开发者工具的时候,我实现了一份 Java ...

  8. android 启动app过程,Android P APP冷启动过程全解析(之四)

    经历了前面的三个阶段,activity终于初始化完毕,终终终于开始显示了和接收事件了!这就是本阶段所要做的工作: 15.新建DecorView 16.新建ViewRootImpl 17.添加到Disp ...

  9. ios双指放大缩小_用PS设计APP过程中改进IOS设计流程的30个秘诀

    设计是一个漫长和痛苦的过程,期间可以用点技巧来减少痛苦,30+ tips to improve your iOS design workflow (in Photoshop)一文总结30个实用的技巧可 ...

  10. android 启动app过程,应用程序进程启动过程

    原标题:应用程序进程启动过程 作者:慕涵盛华 链接:https://www.jianshu.com/p/b158615cc2ad 一.背景 首先注意的是:这里要说的是应用程序进程的启动过程,而不是应用 ...

最新文章

  1. 如何管理多个 SSH 连接
  2. 浅谈ClickableSpan , 实现TextView文本某一部分文字的点击响应
  3. HTML5新特性介绍
  4. ubuntu16.04:成功解决ubuntu16.04 忘记root密码
  5. 一起教育科技递交招股书:收入增速超277.48%,或成纳斯达克最大教育概念股
  6. 《理解 ES6》阅读整理:函数(Functions)(五)Name Property
  7. android 打印kernel log,android8.0 kernel4.9.44 各层log打开
  8. win10子系统 php,启用 Win10 的 Linux 子系统
  9. 数据层优化-jdbc连接池简述、druid简介
  10. 冠军奖金50万,2020腾讯广告算法大赛广发“英雄帖”
  11. SQL系统教程一(表之间的连接关系)
  12. W3CSchool离线文档下载
  13. gamepad android,传说之下虚拟手柄
  14. Android Activity防劫持方案
  15. linux网络配置方法
  16. pageSize不生效
  17. 想改行,学什么技术能看到未来?
  18. 2、java语言基础课程2
  19. 数电课程设计之7段显示器8421BCD码转换器
  20. 小i机器人与腾讯、商汤等发起成立上海人工智能发展联盟

热门文章

  1. 小马哥-----高仿红米note3 市场已出现山寨 警惕 高仿红米note3 J7218刷机外观图与开机识别图
  2. IOS 开发技能图谱——ios 开发工程师必知必会要点
  3. 三分钟学会数据库, INSERT INTO 插入
  4. bash: /home/jdk/jdk1.8.0_261/bin/java: /lib/ld-linux.so.2: bad ELF interpre问题
  5. stc单片机“全自动下载”(程序版)
  6. 糖友日常生活需要注意什么
  7. 三星Q990B全景声回音壁评测
  8. 面试经验(妙计旅行:C++算法工程师)
  9. css动画小案例(太阳地球月球运动轨迹)
  10. 独孤九剑第二式-Logistic回归模型