组网使用教程
一、概述
MSDK2.5版本、无人机固件1.8版本支持组网功能。允许将多个遥控器和多架无人机加入到同一个网络中。组网成功后,在这些设备中有且只有一个主遥控器和一个中继飞机,其它遥控器都为从遥控器,无人机为普通节点飞机。
目前只支持观看一个飞机的码流,单控设备同时需要设置此设备为watch设备。
1.组网模型
2.名词解释
概 念 | 说 明 | 注意 |
---|---|---|
组网(Netmesh) | 设备加入到一个网络 | |
DeviceId | 无人机唯一ID | |
NodeId | 本次组网的节点ID | |
中继机 | 中心节点飞机 | |
主遥控器 | 发起组网的遥控器 | |
从遥控器 | 加入组网的遥控器 | |
单控 | 选择一架无人机并控制 | 同时设置为watch设备 |
全控 | 控制所有无人机 | |
watch | 查看无人机图传码流 |
3.组网角色与权限
角 色 | 控制权限 | 角色切换 | 多码流 |
---|---|---|---|
主遥控器 | 全部权限 | 不能切换 | 可以观看受控飞机的码流 |
从遥控器 | 摇杆不可用 | 不能切换 | 可以观看中受控飞机的码流 |
中继飞机 | - | 可以通过中继替换流程替换 | 可以向所有遥控器推送码流 |
叶子飞机 | - | 可以切换为受控飞机 | 不可推送码流 |
受控飞机 | - | 可以切换为叶子飞机 | 可以向所有遥控器推送码流 |
二、组网相关接口
1. DeviceManager
DeviceManager负责各种设备的创建管理,通过DeviceManager.getMultiDeviceOperator()获组网相关操作接口
interface IMultiDeviceOperator
/**
* 获取组网操作接口
*/
fun getNetMeshManager(): INetMeshManager
/**
* 是否单控
*/
fun isSingleControl(): Boolean
/**
* 是否是组网版本
*/
fun isNetMesh(): Boolean
/**
* 组网:飞机控制变化监听
*/
fun addControlChangeListener(listener: IControlDroneListener)
fun removeControlChangeListener(listener: IControlDroneListener)
/**
* 组网:watch飞机变化监听
*/
fun addWatchChangeListener(listener: IWatchDroneListener)
fun removeWatchChangeListener(listener: IWatchDroneListener)
/**
* 获取飞行器列表
*/
fun getDroneDevices(): List<IAutelDroneDevice>
/**
* 获取遥控器信息列表
*/
fun getRemoteInfoList(): List<DeviceInfoBean>
/**
* 组网控制模式
*/
fun getControlMode(): ControlMode
/**
* 通过设备id获取飞行器
*/
fun getDroneDeviceById(deviceId: Int): IAutelDroneDevice?
/**
* 通过设备nodeId获取飞行器
*/
fun getDroneDeviceByNodeId(nodeId: Int): IAutelDroneDevice?
/**
* 本地遥控器信息
*/
fun getLocalRemoteDevice(): RemoteDevice
/**
* 获取已经连接飞机的id集合
*/
fun getConnectedDeviceIds(): List<Int>
/**
* 根据deviceIdList得到⻜机设备的keyManagerList
*/
fun generateKeyManagerList(deviceIdList: List<Int>): MutableList<IKeyManager>
/**
* 执⾏多机命令接⼝
*/
fun <Param, Result> performActionList(
deviceIdList: List<Int>, key: AutelKey.ActionKey<Param, Result>, param: Param,
callback: DeviceManager.CompletionCallbackWithParam<DeviceManager.DeviceActionResult<Result>>?
)
/**
* 组网:多机监听接口
*/
fun <Result> addDroneDevicesListener(key: AutelKey<Result>, callbacks: DeviceManager.KeyManagerListenerCallBack)
fun <Result> removeDroneDevicesListener(key: AutelKey<Result>, callbacks: DeviceManager.KeyManagerListenerCallBack)
/**
* 组网:获取中继飞机
*/
fun getCenterDroneDevice(): IAutelDroneDevice?
/**
* 组网:获取所控的在线飞机列表
*/
fun getControlledDroneList(): MutableList<IAutelDroneDevice>
/**
* 组网:获取watch的在线飞机列表
*/
fun getWatchedDroneList(): MutableList<IAutelDroneDevice>
/**
* 组网:是否是主遥控器
*/
fun isMainRC():Boolean
/**
* 组网:设备及控制变化监听
*/
fun addNetMeshChangeListener(listener: IMeshDeviceChangedListener)
fun removeNetMeshChangeListener(listener: IMeshDeviceChangedListener)
}
2. 组网相关接口
主要提供组网相关接口:启动组网/加入组网、添加、删除、重命名设备,设置中继设备,设置Watch设备,切换控制模式,解散组网等功能
interface INetMeshManager {
/**
* 获取设备信息
*/
fun getAllMeshDeviceList():List<DeviceInfoBean>
/**
* 本地遥控器名称
*/
fun getLocalRCName():String?
/**
* 主遥控器名称
*/
fun getMainRCName():String?
/**
* 主遥控器设置的watch设备
*/
fun getMainRcWatchDrone():IAutelDroneDevice?
/**
* 是否正在组网中
*/
fun isNetMeshing():Boolean
/**
* 是否解散了组网
*/
fun isMeshDisband():Boolean
/**
* 开始组网
* @param bean
* @param meshMode 指定最大设备数,但最终依赖飞机固件配置
* @param callback
*/
fun startNetMeshMatching(
bean: CreateDeviceNetworkReq,
meshMode: MeshModeEnum? = MeshModeEnum.STANDARD,
callback: CommonCallbacks.CompletionCallbackWithParam<CreateDeviceNetworkResp>
)
/**
* 完成组网
*/
fun completeNetMeshMatching(
callback: CommonCallbacks.CompletionCallbackWithParam<Int>
)
/**
* 剔除组网设备
*/
fun delNetMeshDevice(
deviceId: Int,
callback: CommonCallbacks.CompletionCallbackWithParam<Int>
)
/**
* 设置为中心结点
*/
fun setCenterNode(
deviceId: Int,
callback: CommonCallbacks.CompletionCallbackWithParam<Int>
)
/**
* 加入组网
*/
fun joinDeviceNetMesh(
joinReq: JoinDeviceNetworkReq?,
callback: CommonCallbacks.CompletionCallbackWithParam<Int>
)
/**
* 解散组网团队
*/
fun disbandNetMesh(
groupId: Long?,
callback: CommonCallbacks.CompletionCallbackWithParam<Int>
)
/**
*退出组网团队
*/
fun quitNetMeshMatching(
groupId: Long?,
callback: CommonCallbacks.CompletionCallbackWithParam<Int>
)
/**
* 设置本地设备在组网团队的名称
*/
fun nameDeviceNetMeshMatching(
editDeviceNameReq: EditDeviceNameReq,
callback: CommonCallbacks.CompletionCallbackWithParam<Int>
)
/**
* 多控模式切换图传,参数 DeviceId
* return : 1:成功 2:失败 0:未知
* */
fun setWatchDevice(
selectDevice: List<Int>?,
callback: CommonCallbacks.CompletionCallbackWithParam<Int>
)
/**
* 组网流控设置
*/
fun setNetMeshStreamControl(streamList: List<CameraStreamInfo>, callback: CommonCallbacks.CompletionCallbackWithParam<Int>)
/**
* 切换控制模式
*/
fun switchControlMode(mode: ControlMode,id: Int,callback: CommonCallbacks.CompletionCallbackWithParam<Void>)
}
3. 飞机事件监听
提供了针对多机组网的设备事件监听,方便多机情况下事件的监听
DeviceManager.getDeviceManager().addDroneDevicesListener(reportKey, devicesListener)
DeviceManager.getDeviceManager().removeDroneDevicesListener(reportKey, devicesListener)
private val devicesListener = object : DeviceManager.KeyManagerListenerCallBack {
override fun onListenerValueChanged(value: DeviceManager.DeviceListenerResult<*>) {
(value.result as? MissionWaypointStatusReportNtfyBean)?.let { bean ->
missionStatusMap[value.drone.getDeviceNumber()] = bean
}
}
}
三、Autel组网功能示例
1.主遥控器
开始组网配对:30s超时,超时后可继续向启动组网
DeviceManager.getMultiDeviceOperator().getNetMeshManager().startNetMeshMatching(bean,callback)
剔除设备:中继设备,无法删除,删除中继设备等于解散组网,调用前需要判断是否要删除的是中继设备,如果是中继设备,则直接调用解散组网
DeviceManager.getMultiDeviceOperator().getNetMeshManager().delNetMeshDevice(id,callback)
设置中继:完成组网前必须先设置中继设备
DeviceManager.getMultiDeviceOperator().getNetMeshManager().setCenterNode(id,callback)
完成组网:完成组网后会重置网络,所有设备连接会短暂断开然后重新连接
DeviceManager.getMultiDeviceOperator().getNetMeshManager().completeNetMeshMatching(callback)
解散组网:会删除所有设备
DeviceManager.getMultiDeviceOperator().getNetMeshManager().disbandNetMesh(groupdId,callback)
修改组网设备名称
DeviceManager.getMultiDeviceOperator().getNetMeshManager().nameDeviceNetMeshMatching(req,callback)
设置控制模式(群组控制:groupId; 单机控制:NodeId; 全选:此参数被忽略)
DeviceManager.getMultiDeviceOperator().getNetMeshManager().switchControlMode(mode, id, callback)
enum class ControlMode(val value: Int) {
/**
* unknown
*/
UNKNOWN(0),
/**
*Group control
*/
GROUP(1),
/**
* single control
*/
SINGLE(2),
/**
* control all
*/
ALL(3);
}
2. 从遥控器
- 加入组网
DeviceManager.getMultiDeviceOperator().getNetMeshManager().joinDeviceNetMesh(req,callback)
- 退出组网
DeviceManager.getMultiDeviceOperator().getNetMeshManager().quitNetMeshMatching(groupdId,callback)
3. 组网监听
设备状态监听(设备生命周期变化)
依次是:设备创建->设备连接变化->设备主服务可用变化->设备能力集变化->设备销毁
interface IAutelDroneListener {
/**
* 组网设备创建
* @param drone drone device
*/
fun onDroneCreate(drone: IAutelDroneDevice){}
/**
* 无人机设备连接状态的监听器
*
* @param connected 已连接 - is connected
* @param drone 无人机装置 - drone device
*/
fun onDroneChangedListener(connected: Boolean, drone: IAutelDroneDevice){}
/**
* 主服务是否可用
* @param valid true 可用,false 不可用
* @param drone drone device
*/
fun onMainServiceValid(valid: Boolean, drone: IAutelDroneDevice) {}
/**
*相机能力集变更通知
* @param localFetched true 本地能力集解析成功
* @param remoteFetched true 远程能力集解析成功
*/
fun onCameraAbilityFetchListener(localFetched: Boolean, remoteFetched: Boolean, drone: IAutelDroneDevice){}
/**
* SDK业务接口报错回调
* @param errorInfo
*/
fun onSDKErrorListener(errorInfo: SDKErrorUtil) {}
/**
* 组网设备销毁
* @param drone drone device
*/
fun onDroneDestroy(drone: IAutelDroneDevice){}
}
设备控制变化(组网过程中触发,用户下发控制切换后触发)
DeviceManager.getMultiDeviceOperator().addControlChangeListener(object : IControlDroneListener {
override fun onControlChange(mode: ControlMode, droneList: List<IAutelDroneDevice>){
}
})
设备watch变化监听
需要监听watch设备的变化,中继飞机有独立的视频通道ID配置,所有的叶子飞机共用一套通道ID配置,所以切换码流需要判断是否为中继飞机,通道配置参看ISDKConstants
DeviceManager.getMultiDeviceOperator().addWatchChangeListener(object:object : IWatchDroneListener {
override fun onWatchChange(droneList: List<IAutelDroneDevice>) {
if(droneList.contans(currentDrone)){
val playerId = DeviceUtils.getPlayerId(droneDevice, lensTypeEnum)
if (playerId != null) {
val autelPlayer = AutelPlayerManager.getInstance().getAutelPlayer(playerId)
if (autelPlayer != null) {
autelPlayer?.removeVideoView()
}
autelPlayer?.addVideoView(renderView)
AutelLog.i("SwitchDrone", "startPlay = " + autelPlayer + " port:" + playerId + " view :" + renderView.toString())
getCurrentAutelPlayerKeyFrame(playerId)
}
}
})