Skip to content

Feature

Zhexuan Liu edited this page Jun 21, 2018 · 1 revision

1. Introduction

1.1 Feature

MeshEngine 定义了一系列 Feature,用以控制飞机执行各种飞行相关的行为。在 MeshEngine 2.0 中,我们进一步加强了 Feature 的执行权限,开发者不能随心所欲,随时随地对 feature 进行调用,而必须遵守一定的规则。而站在用户的角度,这里的规则指的是:所有 Feature 只会在 Handler 页面被执行。

除了 Featrue 以外,同时还提供了

目前提供了如下 Feature,调用方式见后面 Feature 的生命周期控制 部分:

1.2 Action

除了 Feature,MeshEngine 还定义了一系列 Action. 某种意义上 Action 与 Feature “相反”:Feature 控制飞机飞行相关的行为,而 Action 控制飞机飞行以外的行为,例如拍照,录像,云台调整等等。不同的 Feature 可能定义不同的 Action 触发点,比如在 Waypoint Feature 中定义了如下 Action 触发点:

  • resumeAction: Waypoint Feature 恢复执行时,将会触发的 Action;
  • finishAction: 到达某 Waypoint 时将会触发的 Action;

所有 Action 的执行相对与 Feature 都是异步的(如果需要同步,则应该使用 CustomFeature ,详见下方 2.7 的相关讨论)。目前 MeshEngine 中定义了如下 Action:

2. Feature 执行的生命周期

控制 Feature 执行的生命周期的核心在于,在 Feature 开始执行之后,将 Feature 的 Pause/Stop/Resume 管理从 Package 中独立开来,保证 Swift 对 Feature 的管理拥有最高权限,从而保证用户对飞机拥有最高控制权,凌驾于 Package 之上,确保操作的安全性。

FeatureControl 控件:

Start/Resume Pause/Stop

为了简明起见,这里将 Start/Resume 的按钮命名为 Active 按钮,将 Pause/Stop 按钮命名为 Abort 按钮。

2.1. 执行 Feature

在 Package 的开发中,执行 Feature 的方法如下:

mesh.featureExecutor.executeFeatures(array, uuid)

其中 array 的元素为一个 JSON 字典,指定了某个 Feature 执行所需的各种参数。

而 uuid 的生成细节可参阅后面 Start 部分内容

2.2. Start

当用户点击 Active 按钮执行 Start 操作,Swift 会触发事件 featureWillStart,并且带上一个新生成的 uuid 作为执行 feature 的「通行证」,这个 uuid 在用户离开 Handler 页面之后便会失效,从而确保 Feature 只能在恰当的时空执行。

事件 featureWillStart 被触发时附带的数据格式:

{
    "uuid": "xxxxxx"
}

之后 Package 便可以使用此 uuid 来调用 executeFeature 方法。

当 Feature 被成功执行后,Swift 将会触发 featureDidStart 事件,Package 可根据此来做界面上的更新。

而如果开始执行这个 Feature 的时候发生了错误,则会触发 featureStartFail 事件,并带上对应的错误信息:

{
    "error": "xxxx"
}

Start 相关 Event:

事件 描述 数据
featureWillStart 用户点击 Start 按钮时触发,用于向 Package 传递 uuid {"uuid": xxx, "toDeviceId": xxx}
featureDidStart Feature 成功开始执行后被触发 {"toDeviceId": xxx}
featureStartFail Feature 开始执行出错时被触发 {"error": xxx, "toDeviceId": xxx}

2.3. Abort (Pause/Stop)

当用户点击了 FeatureControl 的 Abort 按钮,会触发 Pause/Stop 操作,由 Swift 执行,详细如下:

Pause 相关 Event

事件 描述 数据
featureDidPause Feature 被成功 Pause 之后触发 {"toDeviceId": xxx}
featurePauseFail Pause Feature 出错后被触发 {"error": xxx, "toDeviceId": xxx}

Stop 相关 Event

事件 描述 数据
featureDidStop Feature 被成功 Stop 之后触发 See detail below
featureStopFail Stop Feature 出错后被触发 See detail below

在触发 featureDidStop 以及 featureStopFail 时,Swift 会向 Package 回传数据:

{
	"currentFeatureIndex": 0,
	"error": "Some error if existed",
	"data": {},
	"toDeviceId": xxx
}

其中 data 字段的内容是根据 currentFeatureIndex 所指向的 feature 种类而定,对于不同 Feature,data 字段对应的内容如下:

waypointFeature

{
	"currentFeatureIndex": 0,
	"error": "xxx",
	"data": {
		"lastWaypointIndex": 0
	}
}

lastWaypointIndex 表示最近一次到达的航点的索引,没有则为 -1(飞往第一个点的过程中被 Stop)。

customFeature

{
	"currentFeatureIndex": 0,
	"error": "xxx",
	"data": {
		"currentStepIndex": 0,
		"lastWaypointIndex": x // Woudl be returned if current step is waypoint step
	}
}

currentStepIndex 表示 CustomFeature 被 Stop 时正在执行的 Step 的索引。

2.4. Active (Resume/Start)

当用用户点击 Active 按钮,Swift 按照以下逻辑进行判断处理:

Resume 相关 Event

事件 描述 数据
featureDidResume Feature 被成功 Resume 之后触发 {"toDeviceId": xxx}
featureResumeFail Resume Feature 出错后被触发 {"toDeviceId": xxx, "error": xxx }

2.5. Finish

Finish 相关 Event

事件 描述 数据
featureDidFinish Feature 顺利执行完毕后被触发 See detail below
featureExecuteFail Feature 由于自身执行出错而被中止 See detail below

在触发 featureDidFinish 以及 featureExecuteFail 时附带向 Package 回传数据,数据格式与 Stop 相关事件被触发时的回传数据一致。

2.6. Execution Process

Execution Process 相关 Event

事件 描述 数据
featureExecutionProgress 事件的触发条件见下方详细描述 See detail below

由于 CustomFeature 以及 WaypointFeature 是以序列的方式定义的,他们都由一系列的元素组成:

  • CustomFeature 接受一系列 Step,每个 Step 指定其需要完成的工作,CustomFeature 执行的时候按顺序依次执行每个 Step;
  • WaypointFeature 接受一系列的 Waypoint,每个 Waypoint 指定一个 GPS 坐标,WaypointFeature 被执行时,飞机按顺序依次飞往每个指定的坐标;

对于这类序列形式的 Feature,Swift 通过 featureExecutionProgress 向 Package 回传其执行状态,在触发 featureExecutionProgress 的同时附带向 Package 回传数据。数据格式与 Stop 相关事件被触发时的回传数据类似。触发时机为:

  • WaypointFeature: 飞机开始飞向下一个目标点时;

lastWaypointIndex 代表上一个到达的航点索引;

  • CustomFeature: 飞机开始执行下一个 Step 时;

currentStepIndex 代表当前开始执行的 Step 的索引;

2.7. Feature 与 Action 的生命周期关系

在前面 1.2 处关于 Action 的描述中提到:所有 Action 的执行相对与 Feature 都是异步,由此引申出 Feature 与 Action 之间的生命周期关系:

  • Feature 被 Abort (即:暂停/停止)时,相关 Action 会被停止;
  • Action 执行/停止出错时不会干扰 Feature 的生命周期;

对于最后一点,制定此规则的原因是:

  • 飞行相关的操作被终止后恢复的成本比较高;
  • Action 执行出错可手动操作 ActionControl 来解决;

关于 Feature 与 Action 之间的生命周期关系,下面举一个例子帮助理解。如是一个 Waypoint Feature:

根据以上所述 Feature 与 Action 之间的生命周期关系,会有如下结论:

  • 飞机到达 wp3 时将会触发拍照,同时飞向 wp4;
  • 如果 wp3 处的拍照触发失败,飞机仍然会飞向 wp4;
  • 如果 wp3 处触发的是无限间隔拍照,当飞机到达 wp5 时此 Action 将被停止,因为 Feature 已经 Finish 了;
  • 如果 wp3 处触发的是无限间隔拍照,当飞机到达 wp4 时用户触发暂停,此时 Action 会被停止;
  • 如果用户在 wp4 处通过 ActionControl 停止了拍照,飞机照常飞行;
  • 如果飞机在 wp4 处由于 SD Card 已满而以外停止拍照,飞机照常飞行;

**总而言之:**Feature 控制 Action 的生命周期,而 Action 不会影响 Feature 的生命周期。

3. Copilot 协作

上面讨论是基于 Pilot 环境。至于 Copilot 参与协作的情况下,相当于在上面的基础上再批一层 WebSocket 事件转发的外衣。此处的职责划分如下:

如上图所示,Feature 的配置过程中的信息交互由 Package 负责,包括 Feature 的 execute,也是由 Copilot 端的 Package 转发到 Pilot 端的 Package 环境,再由 Pilot 端的 Package 调用相应的 API。

而 Feature Control 相关的交互事件,以及 Feature 生命周期事件,由 Swift 进行转发处理。

因此 Copilot 端的 Package 仍然能从其 Swift 端接收到 featureExecutionProgress 事件,进行界面上的更新。

Clone this wiki locally