Skip to main content

组网使用教程

一、概述

MSDK2.5版本、无人机固件1.8版本支持组网功能。允许将多个遥控器和多架无人机加入到同一个网络中。组网成功后,在这些设备中有且只有一个主遥控器和一个中继飞机,其它遥控器都为从遥控器,无人机为普通节点飞机。

目前只支持观看一个飞机的码流,单控设备同时需要设置此设备为watch设备。

1.组网模型

20230504120703359

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