drone无人机app下载苹果版_drone无人机教程视频

drone无人机app下载苹果版_drone无人机教程视频目录文章目录目录摘要1.实例化无人机及地面站控制对象2.绑定服务3.增加连接点击事件及进行连接摘要本节主要记录HelloDrone的连接过程及Mavlink协议解析过程。1.实例化无人机及地面站控制对象核心内容:controlTower=newControlTower(context);drone=newDrone(context);@Override/***重写onCreate方法,在onStart方法之前启动*/pro

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

目录

摘要

本节主要记录HelloDrone的连接过程及Mavlink协议解析过程。

1.实例化无人机及地面站控制对象

核心内容:

controlTower = new ControlTower(context);
drone = new Drone(context);

    @Override
/** * 重写onCreate方法,在onStart方法之前启动 */
protected void onCreate(Bundle savedInstanceState) { 

//调用父类的onCreate
super.onCreate(savedInstanceState);
//设置主窗口显示信息
setContentView(R.layout.activity_main);
Log.i("lxw","+++++");
//获取app文件名称
final Context context = getApplicationContext();
//创建控制
controlTower = new ControlTower(context);
//创建无人机实例
drone = new Drone(context);
//模式选择
this.modeSelector = (Spinner) findViewById(R.id.modeSelect);
//增加模式选择监听事件
this.modeSelector.setOnItemSelectedListener(new Spinner.OnItemSelectedListener()
{ 

@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{ 

onFlightModeSelected(view);
}
@Override
public void onNothingSelected(AdapterView<?> parent)
{ 

// Do nothing
}
});
final Button takePic = (Button) findViewById(R.id.take_photo_button);
takePic.setOnClickListener(new View.OnClickListener() { 

@Override
public void onClick(View v) { 

takePhoto();
}
});
final Button toggleVideo = (Button) findViewById(R.id.toggle_video_recording);
toggleVideo.setOnClickListener(new View.OnClickListener() { 

@Override
public void onClick(View v) { 

toggleVideoRecording();
}
});
videoView = (TextureView) findViewById(R.id.video_content);
videoView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() { 

@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 

alertUser("Video display is available.");
startVideoStream.setEnabled(true);
startVideoStreamUsingObserver.setEnabled(true);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 

}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 

startVideoStream.setEnabled(false);
startVideoStreamUsingObserver.setEnabled(false);
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) { 

}
});
startVideoStream = (Button) findViewById(R.id.start_video_stream);
startVideoStream.setEnabled(false);
startVideoStream.setOnClickListener(new View.OnClickListener() { 

@Override
public void onClick(View v) { 

alertUser("Starting video stream.");
startVideoStream(new Surface(videoView.getSurfaceTexture()));
}
});
stopVideoStream = (Button) findViewById(R.id.stop_video_stream);
stopVideoStream.setEnabled(false);
stopVideoStream.setOnClickListener(new View.OnClickListener() { 

@Override
public void onClick(View v) { 

alertUser("Stopping video stream.");
stopVideoStream();
}
});
startVideoStreamUsingObserver = (Button) findViewById(R.id.start_video_stream_using_observer);
startVideoStreamUsingObserver.setEnabled(false);
startVideoStreamUsingObserver.setOnClickListener(new View.OnClickListener() { 

@Override
public void onClick(View v) { 

alertUser("Starting video stream using observer for video stream packets.");
startVideoStreamForObserver();
}
});
stopVideoStreamUsingObserver = (Button) findViewById(R.id.stop_video_stream_using_observer);
stopVideoStreamUsingObserver.setEnabled(false);
stopVideoStreamUsingObserver.setOnClickListener(new View.OnClickListener() { 

@Override
public void onClick(View v) { 

alertUser("Stopping video stream using observer for video stream packets.");
stopVideoStreamForObserver();
}
});
// Initialize media codec manager to decode video stream packets.
HandlerThread mediaCodecHandlerThread = new HandlerThread("MediaCodecHandlerThread");
mediaCodecHandlerThread.start();
Handler mediaCodecHandler = new Handler(mediaCodecHandlerThread.getLooper());
mediaCodecManager = new MediaCodecManager(mediaCodecHandler);
mainHandler = new Handler(getApplicationContext().getMainLooper());
}

2.绑定服务

    @Override
public void onStart()
{ 

Log.i("lxw","Hello Drone onStart启动");
super.onStart();
//执行连接任务
Log.i(MAGTAG,"onStart");
Log.i(MAGTAG,"this:"+this); //this:hello.MainActivity
Log.i(MAGTAG,"this2:"+getApplicationContext()); //this2:hello.StarterApplication
//执行控制器连接
this.controlTower.connect(this,getApplicationContext());
//更新模式类型
updateVehicleModesForType(this.droneType);
Log.i(MAGTAG,"connect");
}

核心代码是:

this.controlTower.connect(this,getApplicationContext());

实现服务的绑定o3drServicesConnection

    public void connect(TowerListener listener,Context context) { 

boolean value;
Log.i("LXW","AAA");
//没有监听这,条件判断
if (towerListener != null && (isServiceConnecting.get() || isTowerConnected()))
return;
//是空
if (listener == null)
{ 

throw new IllegalArgumentException("ServiceListener argument cannot be null.");
}
Log.i("LXW","CCC");
towerListener = listener;
Log.i("LXW","DDD");
if (!isTowerConnected() && !isServiceConnecting.get())
{ 

Intent serviceIntent = ApiAvailability.getInstance().getAvailableServicesInstance(context);
//value1:Intent { act=com.o3dr.services.android.lib.model.IDroidPlannerServices
// cmp=com.o3dr.sample.hellodrone/org.droidplanner.services.android.impl.api.DroidPlannerService }
Log.i("LXW","value1:"+ApiAvailability.getInstance().getAvailableServicesInstance(context));
value= this.context.bindService(serviceIntent, o3drServicesConnection, Context.BIND_AUTO_CREATE);
//value2:true
Log.i("LXW","value2:"+value);
isServiceConnecting.set(value);
}
Log.i("LXW","EEE");
}

绑定服务后,首先启动的是onCreate(),然后进行onBind()方法
在这里插入图片描述
我们需要在清单文件中声明服务
在这里插入图片描述
我们去看下DroidPlannerService的代码,发现他是继承Service的,这也满足了服务的要求。


/** DroneKit安卓后台服务实现。 * DroneKit-Android background service implementation. */
public class DroidPlannerService extends Service { 

/** * Status bar notification id */
private static final int FOREGROUND_ID = 101;
/** * Set of actions to notify the local app's components of the service events. */
public static final String ACTION_DRONE_CREATED = Utils.PACKAGE_NAME + ".ACTION_DRONE_CREATED";
public static final String ACTION_DRONE_DESTROYED = Utils.PACKAGE_NAME + ".ACTION_DRONE_DESTROYED";
public static final String ACTION_RELEASE_API_INSTANCE = Utils.PACKAGE_NAME + ".action.RELEASE_API_INSTANCE";
public static final String EXTRA_API_INSTANCE_APP_ID = "extra_api_instance_app_id";
/** * Used to broadcast service events. */
private LocalBroadcastManager lbm;
/** * Stores drone api instances per connected client. The client are denoted by their app id. */
final ConcurrentHashMap<String, DroneApi> droneApiStore = new ConcurrentHashMap<>();
/** * Caches drone managers per connection type. */
final ConcurrentHashMap<ConnectionParameter, DroneManager> droneManagers = new ConcurrentHashMap<>();
private DPServices dpServices;
private CameraInfoLoader cameraInfoLoader;
private List<CameraDetail> cachedCameraDetails;
/** * Generate a drone api instance for the client denoted by the given app id. * * @param listener Used to retrieve api information. * @param appId Application id of the connecting client. * @return a IDroneApi instance */
DroneApi registerDroneApi(IApiListener listener, String appId) { 

if (listener == null)
return null;
DroneApi droneApi = new DroneApi(this, listener, appId);
droneApiStore.put(appId, droneApi);
lbm.sendBroadcast(new Intent(ACTION_DRONE_CREATED));
updateForegroundNotification();
return droneApi;
}
/** * Release the drone api instance attached to the given app id. * * @param appId Application id of the disconnecting client. */
void releaseDroneApi(String appId) { 

if (appId == null)
return;
DroneApi droneApi = droneApiStore.remove(appId);
if (droneApi != null) { 

Timber.d("Releasing drone api instance for " + appId);
droneApi.destroy();
lbm.sendBroadcast(new Intent(ACTION_DRONE_DESTROYED));
updateForegroundNotification();
}
}
/** * 使用给定的连接参数与车辆建立连接。 * Establish a connection with a vehicle using the given connection parameter. * * @param connParams 用于连接到车辆的参数---Parameters used to connect to the vehicle. * @param appId 连接应用程序的客户端id---Application id of the connecting client. * @param listener 回调以接收无人机事件。Callback to receive drone events. * @return 一个DroneManager实例,充当连接的车辆和正在侦听的客户端之间的路由器。 * A DroneManager instance which acts as router between the connected vehicle and the listeneing client(s). */
DroneManager connectDroneManager(ConnectionParameter connParams, String appId, DroneApi listener) { 

if (connParams == null || TextUtils.isEmpty(appId) || listener == null)
{ 

Log.i("lxw","connectDroneManager NULL");
return null;
}
DroneManager droneMgr = droneManagers.get(connParams);
Log.i("lxw","MYdroneMgr:"+droneMgr);
if (droneMgr == null) { 

final DroneManager temp = DroneManager.generateDroneManager(getApplicationContext(), connParams, new Handler(Looper.getMainLooper()));
Log.i("lxw","temp:"+temp);
droneMgr = droneManagers.putIfAbsent(connParams, temp);
Log.i("lxw","MYdroneMgr2:"+droneMgr);
if(droneMgr == null){ 

Log.i("lxw","Generating:");
Timber.d("Generating new drone manager.");
droneMgr = temp;
}
else{ 

temp.destroy();
}
}
Timber.d("Drone manager connection for " + appId);
Log.i("lxw","Generating connect");
//进行连接
droneMgr.connect(appId, listener, connParams);
return droneMgr;
}
/** * Disconnect the given client from the vehicle managed by the given drone manager. * * @param droneMgr Handler for the connected vehicle. * @param clientInfo Info of the disconnecting client. */
void disconnectDroneManager(DroneManager droneMgr, DroneApi.ClientInfo clientInfo) { 

if (droneMgr == null || clientInfo == null || TextUtils.isEmpty(clientInfo.appId))
return;
String appId = clientInfo.appId;
Timber.d("Drone manager disconnection for " + appId);
droneMgr.disconnect(clientInfo);
if (droneMgr.getConnectedAppsCount() == 0) { 

Timber.d("Destroying drone manager.");
droneMgr.destroy();
droneManagers.remove(droneMgr.getConnectionParameter());
}
}
/** * Retrieves the set of camera info provided by the app. * * @return a list of {@link CameraDetail} objects. */
synchronized List<CameraDetail> getCameraDetails() { 

if (cachedCameraDetails == null) { 

List<String> cameraInfoNames = cameraInfoLoader.getCameraInfoList();
List<CameraInfo> cameraInfos = new ArrayList<>(cameraInfoNames.size());
for (String infoName : cameraInfoNames) { 

try { 

cameraInfos.add(cameraInfoLoader.openFile(infoName));
} catch (Exception e) { 

Timber.e(e, e.getMessage());
}
}
List<CameraDetail> cameraDetails = new ArrayList<>(cameraInfos.size());
for (CameraInfo camInfo : cameraInfos) { 

cameraDetails.add(new CameraDetail(camInfo.name, camInfo.sensorWidth,
camInfo.sensorHeight, camInfo.sensorResolution, camInfo.focalLength,
camInfo.overlap, camInfo.sidelap, camInfo.isInLandscapeOrientation));
}
cachedCameraDetails = cameraDetails;
}
return cachedCameraDetails;
}
@Override
//这里是不是返回null了
public IBinder onBind(Intent intent) { 

Log.d("lxw","onBind service " + intent);
final String action = intent.getAction();
if (IDroidPlannerServices.class.getName().equals(action))
{ 

// Return binder to ipc client-server interaction.
return dpServices;
} else
{ 

return null;
}
}
@SuppressLint("NewApi")
@Override
public void onCreate() { 

super.onCreate();
Log.d("lxw","Binding DroidPlannerService onCreate " );
Timber.d("Creating DroneKit-Android.");
final Context context = getApplicationContext();
dpServices = new DPServices(this);
lbm = LocalBroadcastManager.getInstance(context);
this.cameraInfoLoader = new CameraInfoLoader(context);
updateForegroundNotification();
}
@SuppressLint("NewApi")
private void updateForegroundNotification() { 

final Context context = getApplicationContext();
//Put the service in the foreground
final NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(context)
.setContentTitle("DroneKit-Android")
.setPriority(NotificationCompat.PRIORITY_MIN)
.setSmallIcon(R.drawable.ic_stat_notify);
final int connectedCount = droneApiStore.size();
if (connectedCount > 1) { 

notifBuilder.setContentText(connectedCount + " connected apps");
}
final Notification notification = notifBuilder.build();
startForeground(FOREGROUND_ID, notification);
}
@Override
public void onDestroy() { 

super.onDestroy();
Timber.d("Destroying DroneKit-Android.");
for (DroneApi droneApi : droneApiStore.values()) { 

droneApi.destroy();
}
droneApiStore.clear();
for (DroneManager droneMgr : droneManagers.values()) { 

droneMgr.destroy();
}
droneManagers.clear();
dpServices.destroy();
stopForeground(true);
//Disable this service. It'll be reenabled the next time its local client needs it.
enableDroidPlannerService(getApplicationContext(), false);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) { 

Log.i("lxw","MYintent:"+intent);
if (intent != null) { 

final String action = intent.getAction();
switch (action) { 

case ACTION_RELEASE_API_INSTANCE:
final String appId = intent.getStringExtra(EXTRA_API_INSTANCE_APP_ID);
releaseDroneApi(appId);
break;
}
}
stopSelf();
return START_NOT_STICKY;
}
/** * Toggles the DroidPlannerService component * @param context * @param enable */
public static void enableDroidPlannerService(Context context, boolean enable){ 

final ComponentName serviceComp = new ComponentName(context, DroidPlannerService.class);
final int newState = enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
context.getPackageManager().setComponentEnabledSetting(serviceComp, newState, PackageManager.DONT_KILL_APP);
}
}

执行完onbind后,会返回
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然后会执行

    /** * 创建连接服务 */
private final ServiceConnection o3drServicesConnection = new ServiceConnection() { 

@Override
public void onServiceConnected(ComponentName name, IBinder service) { 

isServiceConnecting.set(false);
Log.i("lxw","onServiceConnected");
o3drServices = IDroidPlannerServices.Stub.asInterface(service);
try { 

o3drServices.asBinder().linkToDeath(binderDeathRecipient, 0);
Log.i("lxw","onServiceConnected try ");
//通知连接
notifyTowerConnected();
} catch (RemoteException e) { 

//通知没有连接
notifyTowerDisconnected();
}
}
@Override
public void onServiceDisconnected(ComponentName name) { 

Log.i("lxw","EEE777");
isServiceConnecting.set(false);
notifyTowerDisconnected();
}
};

核心函数:notifyTowerConnected()

    /** * 通知连接 */
void notifyTowerConnected()
{ 

Log.i("lxw","notifyTowerConnected");
if (towerListener == null)
return;
//调用连接
Log.i("lxw","onTower");
towerListener.onTowerConnected();
}

我们关注这个函数:towerListener.onTowerConnected();主要实现注册无人机和注册监听者。

    public void onTowerConnected() { 

//提示连接成功
alertUser("DroneKit-Android Connected");
this.controlTower.registerDrone(this.drone, this.handler);
Log.i("lxw","onTowerConnected");
this.drone.registerDroneListener(this);
Log.i("lxw","registerDroneListener");
}

3.增加连接点击事件及进行连接

在这里插入图片描述
MainActivity实现点击按钮事件

    public void onBtnConnectTap(View view)
{ 

//判断是否连接状态,如果是连接,点击的话,提示端口连接
if (this.drone.isConnected())
{ 

Log.i("lxw","端开连接");
this.drone.disconnect();
} else
{ 

Log.i("lxw","进行连接");
//Spinner提供了从一个数据集合中快速选择一项值的办法。默认情况下Spinner显示的是当前选择的值,
// 点击Spinner会弹出一个包含所有可选值的dropdown菜单,从该菜单中可以为Spinner选择一个新值
Spinner connectionSelector = (Spinner) findViewById(R.id.selectConnectionType);
//获取到下拉框属性
int selectedConnectionType = connectionSelector.getSelectedItemPosition();
//判断现在的连接是不是USB连接,如果是的话进行usb连接,否则是udp连接
//conntParams:ConnectionParameter{connectionType=0, paramsBundle=[extra_usb_baud_rate=115200]}
ConnectionParameter connectionParams = selectedConnectionType == ConnectionType.TYPE_USB
? ConnectionParameter.newUsbConnection(null)
: ConnectionParameter.newUdpConnection(null);
Log.i("lxw","connectionParams:"+connectionParams);
//内部类实现连接事件
this.drone.connect(connectionParams, new LinkListener()
{ 

@Override
public void onLinkStateUpdated(@NonNull LinkConnectionStatus connectionStatus)
{ 

Log.i("lxw","connectionStatus:"+connectionStatus);
}
});
}
}

核心代码:匿名内部类实现连接事件

            //匿名内部类实现连接事件
this.drone.connect(connectionParams, new LinkListener()
{ 

@Override
public void onLinkStateUpdated(@NonNull LinkConnectionStatus connectionStatus)
{ 

Log.i("lxw","connectionStatus:"+connectionStatus);
}
});
    public void connect(ConnectionParameter connParams, LinkListener linkListener) { 

Log.i("lxw","开始进行drone连接操作");
//USB连接
VehicleApi.getApi(this).connect(connParams);
this.connectionParameter = connParams;
this.linkListener = linkListener;
Log.i("lxw","this.connectionParameter:"+this.connectionParameter);
Log.i("lxw","this.linkListener:"+this.linkListener);
}

继续研究核心代码:VehicleApi.getApi(this).connect(connParams);

    public void connect(ConnectionParameter parameter) { 

Bundle params = new Bundle();
//params:Bundle[{}]
Log.i("lxw","Bundle params:"+params);
params.putParcelable(EXTRA_CONNECT_PARAMETER, parameter);
Action connectAction = new Action(ACTION_CONNECT, params);
//无人机执行异步操作
//com.o3dr.services.android.lib.model.action.Action
Log.i("lxw","Bundle connectAction:"+connectAction);
drone.performAsyncAction(connectAction);
}

分析:drone.performAsyncAction(connectAction);

    public boolean performAsyncAction(Action action) { 

//异步执行线程
return performAsyncActionOnDroneThread(action, null);
}

分析代码:performAsyncActionOnDroneThread

    public boolean performAsyncActionOnDroneThread(Action action, AbstractCommandListener listener) { 

//执行异步行为处理
return performAsyncActionOnHandler(action, this.handler, listener);
}

分析performAsyncActionOnHandler

    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.DroneApi
Log.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));
在这里插入图片描述

    /** * 执行行为 */
public void executeAction(Action action, ICommandListener listener) throws RemoteException { 

//com.o3dr.services.android.lib.model.action.Action
Log.i("lxw","executeAction action:"+action);
if (action == null)
{ 

Log.i("lxw","action null:");
return;
}
String type = action.getType();
//type com.o3dr.services.android.action.CONNECT
Log.i("lxw","type:"+type);
if (type == null)
{ 

Log.i("lxw","type null:");
return;
}
Bundle data = action.getData();
Log.i("lxw","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);
switch (type) { 

// CONNECTION ACTIONS
case 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 ACTIONS
case 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 ACTIONS
case 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) { 

droneMgr.executeAsyncAction(clientInfo, action, listener);
} else { 

CommonApiUtils.postErrorEvent(CommandExecutionError.COMMAND_FAILED, listener);
}
break;
}
}

这里我们选择USB连接,重点执行的函数

在这里插入代码片


/** * 执行连接任务 * @param connParams */
public void connect(ConnectionParameter connParams) { 

try { 

Log.i("lxw","connParams:"+connParams);
//Validate the given connection parameter
connParams = checkConnectionParameter(connParams);
Log.i("lxw","connParams1:"+connParams);
//Validate the current connection parameter for the drone
ConnectionParameter currentConnParams = this.connectionParams == null
? this.connectionParams
: checkConnectionParameter(this.connectionParams);
Log.i("lxw","currentConnParams:"+currentConnParams);
if (!connParams.equals(currentConnParams))
{ 

Log.i("lxw","droneMgr:"+droneMgr);
if (this.droneMgr != null)
{ 

Log.i("lxw","droneMgr is not null:");
LinkConnectionStatus connectionStatus = LinkConnectionStatus
.newFailedConnectionStatus(LinkConnectionStatus.ADDRESS_IN_USE,
"Connection already started with different connection parameters");
onConnectionStatus(connectionStatus);
return;
}
this.connectionParams = connParams;
Log.i("lxw","this.connectionParams:"+this.connectionParams);
//ownerId:com.o3dr.sample.hellodrone
Log.i("lxw","ownerId:"+ownerId);
//进行连接管理调用
this.droneMgr = service.connectDroneManager(this.connectionParams, ownerId, this);
Log.i("lxw","this.droneMgr:"+this.droneMgr);
Log.i("lxw","bufdata:"+isEventsBufferingEnabled());
if(isEventsBufferingEnabled())
{ 

Log.i("lxw","isEventsBufferingEnabled:");
eventsBuffer.clear();
handler.postDelayed(eventsDispatcher, this.connectionParams.getEventsDispatchingPeriod());
}
}
} catch (ConnectionException e)
{ 

Log.i("lxw","link connect:");
LinkConnectionStatus connectionStatus = LinkConnectionStatus
.newFailedConnectionStatus(LinkConnectionStatus.INVALID_CREDENTIALS, e.getMessage());
onConnectionStatus(connectionStatus);
disconnect();
}
}

分析代码:this.droneMgr = service.connectDroneManager(this.connectionParams, ownerId, this);

    /** * 使用给定的连接参数与车辆建立连接。 * Establish a connection with a vehicle using the given connection parameter. * * @param connParams 用于连接到车辆的参数---Parameters used to connect to the vehicle. * @param appId 连接应用程序的客户端id---Application id of the connecting client. * @param listener 回调以接收无人机事件。Callback to receive drone events. * @return 一个DroneManager实例,充当连接的车辆和正在侦听的客户端之间的路由器。 * A DroneManager instance which acts as router between the connected vehicle and the listeneing client(s). */
DroneManager connectDroneManager(ConnectionParameter connParams, String appId, DroneApi listener) { 

if (connParams == null || TextUtils.isEmpty(appId) || listener == null)
{ 

Log.i("lxw","connectDroneManager NULL");
return null;
}
DroneManager droneMgr = droneManagers.get(connParams);
Log.i("lxw","MYdroneMgr:"+droneMgr);
if (droneMgr == null) { 

final DroneManager temp = DroneManager.generateDroneManager(getApplicationContext(), connParams, new Handler(Looper.getMainLooper()));
Log.i("lxw","temp:"+temp);
droneMgr = droneManagers.putIfAbsent(connParams, temp);
Log.i("lxw","MYdroneMgr2:"+droneMgr);
if(droneMgr == null){ 

Log.i("lxw","Generating:");
Timber.d("Generating new drone manager.");
droneMgr = temp;
}
else{ 

temp.destroy();
}
}
Timber.d("Drone manager connection for " + appId);
Log.i("lxw","Generating connect");
//进行连接
droneMgr.connect(appId, listener, connParams);
return droneMgr;
}

分析代码:droneMgr.connect(appId, listener, connParams);

    public synchronized void connect(String appId, DroneApi listener, ConnectionParameter connParams) { 

//org.droidplanner.services.android.impl.api.DroneApi
Log.i("lxw","listener:"+listener);
Log.i("lxw","listener2:"+TextUtils.isEmpty(appId));
if (listener == null || TextUtils.isEmpty(appId)) { 

Log.i("lxw","listener return:");
return;
}
connectedApps.put(appId, listener);
//开始连接
Log.i("lxw","doConnect:");
doConnect(appId, listener, connParams);
}

分析:doConnect(appId, listener, connParams);

    protected void doConnect(String appId, DroneApi listener, ConnectionParameter connParams) { 

Log.i("lxw"," MavlinkDrone Manager doConnect:");
if (mavClient.isDisconnected()) { 

Timber.i("Opening connection for %s", appId);
mavClient.openConnection();
Log.i("lxw"," mavClientdoConnect:1");
} else { 

if (isConnected()) { 

listener.onDroneEvent(DroneInterfaces.DroneEventsType.CONNECTED, drone);
if (!drone.isConnectionAlive())
listener.onDroneEvent(DroneInterfaces.DroneEventsType.HEARTBEAT_TIMEOUT, drone);
}
Log.i("lxw"," mavClientdoConnect:2");
}
mavClient.registerForTLogLogging(appId, connParams.getTLogLoggingUri());
Log.i("lxw"," updateDroneStreamRate:");
updateDroneStreamRate(connParams);
}

重点关注: mavClient.openConnection();

    public synchronized void openConnection()
{ 

if(isConnected() || isConnecting())
{ 

Log.i("lxw"," openConnection:1");
return;
}
final String tag = toString();
//创建Mavlink----Create the mavlink connection
final int connectionType = connParams.getConnectionType();
final Bundle paramsBundle = connParams.getParamsBundle();
Log.i("lxw"," connectionType:"+connectionType); //0
Log.i("lxw"," paramsBundle:"+paramsBundle); //波特率
Log.i("lxw"," mavlinkConn:"+mavlinkConn); //UsbConnection
if(mavlinkConn == null) { 

switch (connectionType) { 

//USB类型
case ConnectionType.TYPE_USB:  //0
final int baudRate = paramsBundle.getInt(ConnectionType.EXTRA_USB_BAUD_RATE,
ConnectionType.DEFAULT_USB_BAUD_RATE);
mavlinkConn = new UsbConnection(context, baudRate);
Log.i("lxw"," mavlinkConn:6"+mavlinkConn);
Timber.i("Connecting over usb.");
break;
//蓝牙类型
case ConnectionType.TYPE_BLUETOOTH:
//Retrieve the bluetooth address to connect to
final String bluetoothAddress = paramsBundle.getString(ConnectionType.EXTRA_BLUETOOTH_ADDRESS);
mavlinkConn = new BluetoothConnection(context, bluetoothAddress);
Timber.i("Connecting over bluetooth.");
break;
//TCP类型
case ConnectionType.TYPE_TCP:
//Retrieve the server ip and port
final String tcpServerIp = paramsBundle.getString(ConnectionType.EXTRA_TCP_SERVER_IP);
final int tcpServerPort = paramsBundle.getInt(ConnectionType
.EXTRA_TCP_SERVER_PORT, ConnectionType.DEFAULT_TCP_SERVER_PORT);
mavlinkConn = new AndroidTcpConnection(context, tcpServerIp, tcpServerPort, new WifiConnectionHandler(context));
Timber.i("Connecting over tcp.");
break;
//UDP类型
case ConnectionType.TYPE_UDP:
final int udpServerPort = paramsBundle
.getInt(ConnectionType.EXTRA_UDP_SERVER_PORT, ConnectionType.DEFAULT_UDP_SERVER_PORT);
mavlinkConn = new AndroidUdpConnection(context, udpServerPort, new WifiConnectionHandler(context));
Timber.i("Connecting over udp.");
break;
//SOLO类型
case ConnectionType.TYPE_SOLO: { 

Timber.i("Creating solo connection");
final String soloLinkId = paramsBundle.getString(ConnectionType.EXTRA_SOLO_LINK_ID, null);
final String linkPassword = paramsBundle.getString(ConnectionType.EXTRA_SOLO_LINK_PASSWORD, null);
mavlinkConn = new SoloConnection(context, soloLinkId, linkPassword);
break;
}
default:
Timber.e("Unrecognized connection type: %s", connectionType);
return;
}
}
Log.i("lxw"," mavlinkConn:7");
Log.i("lxw"," mConnectionListener:"+mConnectionListener);
mavlinkConn.addMavLinkConnectionListener(tag, mConnectionListener);
//Check if we need to ping a server to receive UDP data stream.
if (connectionType == ConnectionType.TYPE_UDP)
{ 

final String pingIpAddress = paramsBundle.getString(ConnectionType.EXTRA_UDP_PING_RECEIVER_IP);
if (!TextUtils.isEmpty(pingIpAddress)) { 

try { 

final InetAddress resolvedAddress = InetAddress.getByName(pingIpAddress);
final int pingPort = paramsBundle.getInt(ConnectionType.EXTRA_UDP_PING_RECEIVER_PORT);
final long pingPeriod = paramsBundle.getLong(ConnectionType.EXTRA_UDP_PING_PERIOD,
ConnectionType.DEFAULT_UDP_PING_PERIOD);
final byte[] pingPayload = paramsBundle.getByteArray(ConnectionType.EXTRA_UDP_PING_PAYLOAD);
((AndroidUdpConnection) mavlinkConn).addPingTarget(resolvedAddress, pingPort, pingPeriod, pingPayload);
} catch (UnknownHostException e) { 

Timber.e(e, "Unable to resolve UDP ping server ip address.");
}
}
}
Log.i("lxw"," mavlinkConn:888");
if (mavlinkConn.getConnectionStatus() == MavLinkConnection.MAVLINK_DISCONNECTED)
{ 

Log.i("lxw"," 开始执行Mavlink 连接");
mavlinkConn.connect(null);
}
}

重点函数:执行mavlink相关mavlinkConn.connect(null);

    public void connect(Bundle extras) { 

Log.i("lxw"," mavlinkConn:999");
if (mConnectionStatus.compareAndSet(MAVLINK_DISCONNECTED, MAVLINK_CONNECTING)) { 

extrasHolder.set(extras);
mLogger.logInfo(TAG, "Starting connection thread.");
Log.i("lxw"," mavlink连接任务创建");
mConnectThread = new Thread(mConnectingTask, "MavLinkConnection-Connecting Thread");
//启动连接
mConnectThread.start();
//报告链接状态
reportConnecting();
}
}
    /** * 启动连接进程。Start the connection process. */
private final Runnable mConnectingTask = new Runnable() { 

@Override
public void run() { 

// Load the connection specific preferences
loadPreferences();
// Open the connection
try { 

Log.i("lxw"," 开始执行打开openConnection run");
openConnection(extrasHolder.get());
Log.i("lxw"," mavlinkConn:111");
} catch (IOException e) { 

Log.i("lxw"," mavlinkConn:2222");
// Ignore errors while shutting down
if (mConnectionStatus.get() != MAVLINK_DISCONNECTED) { 

reportIOException(e);
mLogger.logErr(TAG, e);
}
disconnect();
}
mLogger.logInfo(TAG, "Exiting connecting thread.");
}
};

继续看代码:openConnection(extrasHolder.get());

    @Override
protected void openConnection(Bundle connectionExtras) throws IOException { 

boolean id_device;
Log.i("lxw"," mUsbConnection:"+mUsbConnection);
if (mUsbConnection != null) { 

try { 

Log.i("lxw"," BBB123");
mUsbConnection.openUsbConnection(connectionExtras);
Log.d(TAG, "Reusing previous usb connection.");
return;
} catch (IOException e) { 

Log.i("lxw"," BBB456");
Log.e(TAG, "Previous usb connection is not usable.", e);
mUsbConnection = null;
}
}
id_device=isFTDIdevice(context);
Log.i("lxw","id_device:"+id_device);
if (id_device)
{ 

final UsbConnectionImpl tmp = new UsbFTDIConnection(context, this, mBaudRate);
try { 

tmp.openUsbConnection(connectionExtras);
// If the call above is successful, 'mUsbConnection' will be set.
mUsbConnection = tmp;
Log.d(TAG, "Using FTDI usb connection.");
} catch (IOException e) { 

Log.d(TAG, "Unable to open a ftdi usb connection. Falling back to the open "
+ "usb-library.", e);
}
}
// Fallback
if (mUsbConnection == null) { 

Log.i("lxw"," KKK");
Log.i("lxw"," BT:"+mBaudRate);
Log.i("lxw"," BT2:"+context);
final UsbConnectionImpl tmp = new UsbCDCConnection(context, this, mBaudRate);
Log.i("lxw"," BT3:"+tmp);
// If an error happens here, let it propagate up the call chain since this is the fallback.
tmp.openUsbConnection(connectionExtras);
Log.i("lxw"," BT5:");
mUsbConnection = tmp;
Log.i("lxw"," BT6:"+mUsbConnection);
Log.d(TAG, "Using open-source usb connection.");
}
}

继续看代码:tmp.openUsbConnection(connectionExtras);

    protected void openUsbConnection(Bundle extras) throws IOException { 

Log.i("lxw"," cdc");
extrasHolder.set(extras);
registerUsbPermissionBroadcastReceiver();
// Get UsbManager from Android.
UsbManager manager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
//Get the list of available devices
List<UsbDevice> availableDevices = UsbSerialProber.getAvailableSupportedDevices(manager);
Log.i("lxw"," availableDevices:"+availableDevices);
if (availableDevices.isEmpty())
{ 

Log.i("lxw"," CDC NULL");
Log.d(TAG, "No Devices found");
throw new IOException("No Devices found");
}
//Pick the first device
UsbDevice device = availableDevices.get(0);
if (manager.hasPermission(device))
{ 

openUsbDevice(device, extras);
} else { 

removeWatchdog();
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.schedule(permissionWatchdog, 15, TimeUnit.SECONDS);
Log.d(TAG, "Requesting permission to access usb device " + device.getDeviceName());
manager.requestPermission(device, usbPermissionIntent);
}
}

继续看代码:openUsbDevice(device, extras);

    private void openUsbDevice(UsbDevice device, Bundle extras) throws IOException { 

//从Android获取UsbManager。--- Get UsbManager from Android.
UsbManager manager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
//找到第一个可用的驱动程序。--- Find the first available driver.
final UsbSerialDriver serialDriver = UsbSerialProber.openUsbDevice(manager, device);
if (serialDriver == null) { 

Log.d(TAG, "No Devices found");
throw new IOException("No Devices found");
} else { 

Log.d(TAG, "Opening using Baud rate " + mBaudRate);
try { 

serialDriver.open();
serialDriver.setParameters(mBaudRate, 8, UsbSerialDriver.STOPBITS_1, UsbSerialDriver.PARITY_NONE);
serialDriverRef.set(serialDriver);
onUsbConnectionOpened(extras);
} catch (IOException e)
{ 

Log.e(TAG, "Error setting up device: " + e.getMessage(), e);
try { 

serialDriver.close();
} catch (IOException e2) { 

// Ignore.
}
}
}
}

继续onUsbConnectionOpened(extras);

       protected void onUsbConnectionOpened(Bundle extras) { 

parentConnection.onConnectionOpened(extras);
}
    /** * 打开设备,执行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();
}
}

匿名内部类实现最终mavlink协议处理相关

    private final Runnable mManagerTask = new Runnable() { 

@Override
public void run() { 

Thread sendingThread = null;
Thread loggingThread = null;
try { 

final long connectionTime = System.currentTimeMillis();
mConnectionTime.set(connectionTime);
reportConnect(connectionTime);
// Launch the 'Sending' thread
mLogger.logInfo(TAG, "Starting sender thread.");
Log.i("lxw"," Starting new thread.");
sendingThread = new Thread(mSendingTask, "MavLinkConnection-Sending Thread");
sendingThread.start();
//Launch the 'Logging' thread
mLogger.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.Parser
Log.i("lxw"," parser:"+parser);
//服务解析状态
parser.stats.resetStats();
//创建解析数据数组
final byte[] readBuffer = new byte[READ_BUFFER_SIZE];
while (mConnectionStatus.get() == MAVLINK_CONNECTED)
{ 

//读取bufferSize
int bufferSize = readDataBlock(readBuffer);
//bufferSize=
Log.i("lxw"," bufferSize:"+bufferSize);
handleData(parser, bufferSize, readBuffer);
}
} catch (IOException e) { 

// Ignore errors while shutting down
if (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);
}
}
}
};

其中比较重要的APP往外界发送的内容:
其中比较重要的APP往外界发送的内容:
其中比较重要的APP往外界发送的内容:

    private final Runnable mSendingTask = new Runnable() { 

@Override
public void run() { 

try { 

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

我们这里重点还是关注接收
在这里插入图片描述

核心处理:handleData(parser, bufferSize, readBuffer);
核心处理:handleData(parser, bufferSize, readBuffer);
核心处理:handleData(parser, bufferSize, readBuffer);

        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);
}
}
}
    private void reportReceivedPacket(MAVLinkPacket packet)
{ 

//监听者是否非空
if (mListeners.isEmpty())
{ 

return;
}
for (MavLinkConnectionListener listener : mListeners.values())
{ 

Log.i("lxw"," onReceivePacket:");
//接收数据处理
listener.onReceivePacket(packet);
}
}
        public void onReceivePacket(final MAVLinkPacket packet) { 

Log.i("lxw"," notifyReceivedData:");
listener.notifyReceivedData(packet);
Log.i("lxw"," receivedMsg END:");
}
    public void notifyReceivedData(MAVLinkPacket packet) { 

MAVLinkMessage receivedMsg = packet.unpack();
Log.i("lxw"," receivedMsg:"+receivedMsg);
if (receivedMsg == null)
return;
Log.i("lxw"," MSGID:"+receivedMsg.msgid);
if (receivedMsg.msgid == msg_command_ack.MAVLINK_MSG_ID_COMMAND_ACK)
{ 

Log.i("lxw"," command ack:");
msg_command_ack commandAck = (msg_command_ack) receivedMsg;
handleCommandAck(commandAck);
} else
{ 

Log.i("lxw"," Handler receiveData :");
this.mavLinkMsgHandler.receiveData(receivedMsg);
if (this.drone != null)
{ 

Log.i("lxw"," 核心处理mavlink信息:");
this.drone.onMavLinkMessageReceived(receivedMsg);
}
}
if (!connectedApps.isEmpty())
{ 

Log.i("lxw"," spp :"+connectedApps.values());
//org.droidplanner.services.android.impl.api.DroneApi
for (DroneApi droneEventsListener : connectedApps.values())
{ 

droneEventsListener.onReceivedMavLinkMessage(receivedMsg);
}
}
}

这里的代码有两部分比较重要:带应答和不应答的协议,我们这主要关注不带应答的协议。
在这里插入图片描述
先调用Ardupilot中的方法:

    public void onMavLinkMessageReceived(MAVLinkMessage message) { 

Log.i("lxw","ardupilot message.sysid :"+message.sysid );
if ((message.sysid != this.getSysid()) && !isMavLinkMessageException(message)) { 

// Reject Messages that are not for the system id
return;
}
// Filter Components IDs to be specifically the IDs that can be processed
int compId = message.compid;
if (compId != AUTOPILOT_COMPONENT_ID
&& compId != ARTOO_COMPONENT_ID
&& compId != SiK_RADIO_FIXED_COMPID ){ 

return;
}
if (!getParameterManager().processMessage(message)) { 

getWaypointManager().processMessage(message);
getCalibrationSetup().processMessage(message);
switch (message.msgid) { 

case msg_statustext.MAVLINK_MSG_ID_STATUSTEXT:
// These are any warnings sent from APM:Copter with
// gcs_send_text_P()
// This includes important thing like arm fails, prearm fails, low
// battery, etc.
// also less important things like "erasing logs" and
// "calibrating barometer"
msg_statustext msg_statustext = (msg_statustext) message;
processStatusText(msg_statustext);
break;
case msg_vfr_hud.MAVLINK_MSG_ID_VFR_HUD:
processVfrHud((msg_vfr_hud) message);
break;
case msg_raw_imu.MAVLINK_MSG_ID_RAW_IMU:
msg_raw_imu msg_imu = (msg_raw_imu) message;
mag.newData(msg_imu);
break;
case msg_radio.MAVLINK_MSG_ID_RADIO:
msg_radio m_radio = (msg_radio) message;
processSignalUpdate(m_radio.rxerrors, m_radio.fixed, m_radio.rssi,
m_radio.remrssi, m_radio.txbuf, m_radio.noise, m_radio.remnoise);
break;
case msg_rc_channels_raw.MAVLINK_MSG_ID_RC_CHANNELS_RAW:
rc.setRcInputValues((msg_rc_channels_raw) message);
break;
case msg_servo_output_raw.MAVLINK_MSG_ID_SERVO_OUTPUT_RAW:
rc.setRcOutputValues((msg_servo_output_raw) message);
break;
case msg_camera_feedback.MAVLINK_MSG_ID_CAMERA_FEEDBACK:
getCamera().newImageLocation((msg_camera_feedback) message);
break;
case msg_mount_status.MAVLINK_MSG_ID_MOUNT_STATUS:
processMountStatus((msg_mount_status) message);
break;
case msg_named_value_int.MAVLINK_MSG_ID_NAMED_VALUE_INT:
processNamedValueInt((msg_named_value_int) message);
break;
//*************** Magnetometer calibration messages handling *************//
case msg_mag_cal_progress.MAVLINK_MSG_ID_MAG_CAL_PROGRESS:
case msg_mag_cal_report.MAVLINK_MSG_ID_MAG_CAL_REPORT:
getMagnetometerCalibration().processCalibrationMessage(message);
break;
default:
break;
}
}
Log.i("lxw","super message.sysid :"+message.sysid );
//这里实现调用父类的方法
super.onMavLinkMessageReceived(message);
}
    public void onMavLinkMessageReceived(MAVLinkMessage message) { 

Log.i("lxw","message.sysid :"+message.sysid );
if ( (message.sysid != this.getSysid()) && !isMavLinkMessageException(message) )
{ 

// Reject messages that are not for this drone's system id
return;
}
onHeartbeat(message);
switch (message.msgid) { 

case msg_radio_status.MAVLINK_MSG_ID_RADIO_STATUS:
msg_radio_status m_radio_status = (msg_radio_status) message;
processSignalUpdate(m_radio_status.rxerrors, m_radio_status.fixed, m_radio_status.rssi,
m_radio_status.remrssi, m_radio_status.txbuf, m_radio_status.noise, m_radio_status.remnoise);
break;
case msg_attitude.MAVLINK_MSG_ID_ATTITUDE:
msg_attitude m_att = (msg_attitude) message;
processAttitude(m_att);
break;
case msg_heartbeat.MAVLINK_MSG_ID_HEARTBEAT:
msg_heartbeat msg_heart = (msg_heartbeat) message;
processHeartbeat(msg_heart);
break;
case msg_vibration.MAVLINK_MSG_ID_VIBRATION:
msg_vibration vibrationMsg = (msg_vibration) message;
processVibrationMessage(vibrationMsg);
break;
//*************** EKF State handling ******************//
case msg_ekf_status_report.MAVLINK_MSG_ID_EKF_STATUS_REPORT:
processEfkStatus((msg_ekf_status_report) message);
break;
case msg_sys_status.MAVLINK_MSG_ID_SYS_STATUS:
msg_sys_status m_sys = (msg_sys_status) message;
processSysStatus(m_sys);
break;
case msg_global_position_int.MAVLINK_MSG_ID_GLOBAL_POSITION_INT:
processGlobalPositionInt((msg_global_position_int) message);
break;
case msg_gps_raw_int.MAVLINK_MSG_ID_GPS_RAW_INT:
processGpsState((msg_gps_raw_int) message);
break;
case msg_mission_item.MAVLINK_MSG_ID_MISSION_ITEM:
processHomeUpdate((msg_mission_item) message);
break;
case msg_mission_current.MAVLINK_MSG_ID_MISSION_CURRENT:
missionStats.setWpno(((msg_mission_current) message).seq);
break;
case msg_mission_item_reached.MAVLINK_MSG_ID_MISSION_ITEM_REACHED:
missionStats.setLastReachedWaypointNumber(((msg_mission_item_reached) message).seq);
break;
case msg_nav_controller_output.MAVLINK_MSG_ID_NAV_CONTROLLER_OUTPUT:
msg_nav_controller_output m_nav = (msg_nav_controller_output) message;
setDisttowpAndSpeedAltErrors(m_nav.wp_dist, m_nav.alt_error, m_nav.aspd_error);
break;
}
}

整体协议处理流程就是这样,后续会细致分析。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/170568.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号