Robot App框架

最后更新: 2020/7/27

Robot App框架主要分为四部分:

1.API层:

这一层主要对外提供机器人各种能力的底层API(包括听、说、走、看)、语音API和机器人的运行环境。

2.Component层:

这一层将API层提供的各种底层API进行了封装,将一个或者几个相互关联共同完成某一个功能的API封装成为一个组件。开发者可以直接使用组件来完成某一个功能的开发,而不需要了解各个底层API的具体功能、入参或者出参。

3.Task Template层:

这一层将Component层的各个组件进行了封装和组合,每一个task template能够实现一个较为完整的基础业务功能(例如:导航、引领等)。开发者可以直接修改或者使用task template来实现自己的业务功能和逻辑,而不用关心在业务功能过程中需要使用的各种组件或业务的具体流程和步骤。

4.App template层:

这一层会将各种Task Template进行组合,根据不同的App template生成一个具有完整的逻辑功能和业务的Robot App。此外,当用户在使用Component层提供的组件或者Task Template层提供的任务模版时,用户需要自己实现trigger来做页面的跳转,并实现自己特定的业务逻辑和自定义的UI或者语音控制。

在使用App template层提供的App模版时,用户可以通过自定义工作流,来实现业务功能的调整。

模版框架的使用

每一个任务模版包含Provider、ViewModel、Model、Event和Voice这几个主要文件。

  • Provider.ts:封装能力组件,模板逻辑入口
  • ViewModel.ts:模版的业务逻辑
  • Model.ts:模版的数据模型
  • Voice.ts:业务的语音交互
  • Event.ts:模版的页面跳转事件定义
  • 开发者在使用模版时,需要实现两个文件Screen和Listener。其中:

  • Screen 主要负责业务的具体页面的实现
  • Listener监听Model的变化,实现页面的更新
  • 开发者自定义的页面需要在Navigation中进行注册。当页面进行跳转时,通过trigger发送模版中定义的Event事件,事件被接收之后,会通过Navigation跳转到其它页面执行任务。

    Task之间的跳转采用TriggerManager来管理,TriggerManager基于react-navigation的方法进行封装,目前支持switchNavigator,stackNavigator。两者的区别在于switchNavigator会绑定能力组件的生命周期,随着页面切换能力组件自动卸载。而stackNavigator分为replace和navigate两种,replace也会绑定能力组件生命周期,navigation需要业务自己管理能力组件的生命周期。

    TriggerManager的使用,需要在根Navigator的Options的回调函数中绑定navigation和triggerManager,并设置TriggerManager的类型。TriggerNavigate.switchNavigate对应switchNavigator,TriggerNavigate.replaceNavigate对应stackNavigator的replace,TriggerNavigate.stackNavigate对应stackNavigator的navigate。

     defaultNavigationOptions: ({ navigation }) => {           );  
    triggerManager.setNavigation(
    navigation,
    TriggerNavigate.replaceNavigate

    Task内部的页面跳转,采用react-navigation的嵌套栈,作为根Navigator的子栈,子栈的选择由业务方决定, TriggerManager不会管理子栈,也不会绑定生命周期。

    每个Task都包含Action和Trigger两部分,当task希望切换的时候通过BaseViewModel提供的trigger方法触发事件,在Trigger类中根据事件触发不同的Action,这样可以在只修改Trigger中流的方向就可以方便的把一个task接入其他app中。

    export class WakeUpTrigger extends Trigger {
    public constructor() {
    //trigger channel, 将相同channel的trigger和action进行绑定
    super(TriggerChannel.wakeUp);
    }
    public navSwitch = (from: string, to: string): void => {
    ModuleChangeReportStatus.Instance().switchTask(to);
    };
    public trigger = (protocol: TriggerProtocol): void => {
    //BaseViewModel中通过trigger发送的事件会在这里进行处理
    switch (protocol.eventId) {
    case WakeUpEvent.waitTimeout:
    break;
    default:
    //具体action,下一个任务流向
    this._trigger(TriggerChannel.home, protocol);
    if (protocol.type === -1) {
    ReportUtils.reportWeakUp('4');
    } else {
    ReportUtils.reportWeakUp(protocol.type.toString());
    }
    break;
    }
    };
    }