FuncSDK使用说明书

概述

FuncSDK是EwayOS的编程接口,主要包含emake、文档、example部分。

Function结构介绍

Function是EwayOS中的具体功能层,Function连接HighLevelAI获取机器人检测消息,连接LowLevelAI获得机器人运动控制。Function框架主要机制如下:

Message机制

Function内部使用MessageList机制,所有消息(包含HighLevelAI检测到的周边数据,LowLevelAI发送的运动数据以及Function内部的Timer数据、自定义消息数据)均按到达时间及优先级加入一个消息队列,每个Function内部均存在在一个消息处理线程,该线程读取此消息列表,串行处理各消息。

对于自定义消息,首先定义消息码,FunMsg_User之后的数字均可使用。之后在cpp文件中添加消息响应函数,最后在cpp文件中BEGIN_FIFEMSG_MAP与END_FIFMSG_MAP宏之间添加消息映射。

Example:在头文件中添加

#define MuFunMsg FunMsg_User+1
eint OnMyMessage(eint nMsgPri,edouble dTimeStamp,eint nParam1,eint nParam2);

在.cpp文件中END_FIFMSG_MAP前添加

MSG_FIFMAP(MuFunMsg,OnMyMessage)

之后在调用PushIntoMsgList即可将消息插入消息队列,消息处理线程会自动调用OnMyMessage处理消息。

Feature机制

Feature为Function向HighLevelAI请求某项识别、检测功能所使用。Function欲开启某项识别或检测功能时,需在Initialize时或Function运行的任何时间内调用RequestFeature请求Feature,请求成功后Function模块即会收到对应的识别、检测消息,此时框架回调用CheckMsgCode回调询问处理方式,若返回MsgProcCode_Ignore,该消息会被直接丢弃; 若返回MsgProcCode_Notify,框架回调用对应的Proc开头的函数进行回调通知; 若返回MsgProcCode_Record,框架会将消息数据存储,Function模块可调用GetMsgData函数获取最新一次消息数据。

所有请求成功的Feature应在不需要该功能时再次调用RequestFeature关闭。

请求、关闭Feature应在HighLevelAI online后,在调用Destroy前。建议在Initialize时请求Feature,在不需要该功能时随时关闭,若本Function模块可被父Function强制关闭,则应在ProcCloseCmd中关闭Feature。

若请求Feature成功后HighLevelAI掉线,Function不需重新请求Feature,框架会在HighLevelAI上线后自动重新请求。

若在Function请求Feature成功后,由于Sensor原因造成Feature检测错误,Function会收到ProcFeatureStatus回调。

目前支持的FeatureCode如下:

宏名 FeatureCode 数据
SysCom_ID_Vision_Marker 51 视觉Marker
SysCom_ID_Vision_Object 52 视觉物体识别
SysCom_ID_Vision_Face 53 视觉人脸识别
SysCom_ID_Voice_Speech 9050 听觉语音识别
SysCom_ID_LMsg_Obst 10052 障碍检测传感器
SysCom_ID_LMsg_RobPos 10053 机器人位置
SysCom_ID_LMsg_ArmPos 10054 机器人手臂位置
SysCom_ID_LMsg_HeadPos 10055 机器人头部位置

Initialize机制

Function在启动时必须要初始化资源,等资源初始化完成之后,系统会调入JobStart函数,开始Function真正的工作。

Initialize为Function初始化函数,它有两个参数,FeatureList和LimbList。用户需要填入本Function能正常运行所需要的所有Feature和Limbs,等系申请成功后会自动调入JobStart中,如果系统没有申请成功,则调用JobFailed函数。

如果在初始化时,没有填入任何Feature和Limbs,表示Function不需要Sensor的Feature数据和LowLevelAI的Limb控制权,系统会直接调入JobStart中,开始Function的工作。

Command机制

Command为Function向LowLevelAI发送运动指令,控制机器人运动所使用。

Command欲控制机器人运动时,可调用Send系列函数发送运动命令。LowLevelAI收到Send系列控制函数后,首先检查权限,权限正常后及发送返回值至Function,运动函数返回,此时机器人还未开始运动,之后LowLevelAI开始规划运动轨迹,发送电机指令控制机器人运动。当指令发送完毕,等待下位机执行结束后,LowLevelAI会发送CommandDone消息至Function,通知Function该指令执行完毕。Function使用CmdSN识别CommandDone与之前发送的运动指令。

若在Function请求肢体控制权成功后,由于LowLevelAI下线或其它高优先级Function上下线原因造成肢体控制权变化,Function会收到ProcAuthChanged回调。

备注: CommandDone消息可能会传递执行失败消息,(m_nCmdStatus不为0)。此时m_nCmdStatus变量存储错误码。 对于控制电机速度系列指令(SendWheelStraightSpeedSendWheelCycleSpeedSendMotorSpeed),CommandDone消息会立刻发出,指令若未被后续指令取消,会持续执行2.4s。

子Function机制

Function模块共有两种编写方式,一种生成独立app(emake -t fapp)或编译为lib库(emake -t flib),当编译为lib库时,该Function可作为子Function被其它Function调用(app及lib均可)。调用方式为父Function调用AddChildFun函数,参数传入被调用lib库名去掉lib前缀及.so后缀。框架会自动实例化该子Function模块,将其连入HighLevelAI及LowLevelAI,子Function可获取消息数据,可发送肢体控制指令控制机器人运动。

父Function与子Function通过Parameter进行通信。Parameter在传递过程中被序列化为json字符串,用户可调用SetParamStr函数将参数对序列化为json字符串,父Function可随时调用SetChildParam函数向子Function发送参数,子Function收到参数后框架会调用ProcSetFunParam进行通知,子Function可调用GetParam系列函数(GetParamFloatVal,GetParamGuidVal,GetParamIntVal,GetParamStrVal)解析json串,获取最终的参数数值。

子Function退出可选择两种方式,主动退出或被动退出。主动退出为子Function任务执行完毕,关闭Feature及肢体控制权,显式调用FunQuit函数通知父Function退出。调用FunQuit后,框架回调用子Function的Destroy函数,之后关闭消息处理线程,子Function退出。框架会调用父Function的ProcChildFunQuit回调通知父Function。被动退出为父Function调用PostStopCmdToAllChildFunPostStopCmdToChildFunByID函数通知子Function退出,框架会调用子Function的ProcCloseCmd回调通知子Function,此时子Function应立刻关闭Feature及肢体控制权,关闭timer,尽快调用FunQuit退出。调用FunQuit之后的流程与主动退出相同。

子FunQuit后可传递ResultStr至父Function,ResultStr同样使用json串,函数可调用SetParamStr序列化参数对,使用GetParam系列函数解析json串。

Timer机制

Function可使用SetTimer函数开关timer,参数为间隔ms数。当间隔时间到达后,框架会向Function消息队列中插入一条Timer事件,当消息处理线程处理此消息时,会调用ProcTimer函数进行处理。

备注: * 此Timer为非精准Timer,时间间隔为传递消息的最小时间间隔。

若由于程序问题造成消息处理线程响应不及时,可能会造成Timer事件在队列中累计,出现一个时段无ProcTimer,另一时段ProcTimer函数频繁调用。

自定义Message机制

FunctionSDK为自定义Message提供一种临时解决方案。用户可以根据需求自定义Feature和Message,自定义的Message必须继承CBaseMessage类,并实现其中的Serilize,Deserilize,opreator =,clear和copy函数, 详情请参看自定义Message示例。在EwayOS中Sensor产生的数据最终会流入到Function模块中,如果想在Function中接收Sensor中自定义的Message需要在Function中注册这个Message,两个模块引用相同的自定义Message头文件,注册的方式为在cpp文件中加入宏定义,如要在Fucntion中自定义一个CMyMessgae类型的消息,其FeatureCode为1071,消息的描述为“msginfo”,定义方式如下:

  RegisterMessage_Start
  RegisterMessage(1071,CMyMessage,"msginfo")
  RegisterMessage_End

其中CMyMessga必须为CBaseMessage的子类。自定义Message跟框架中原有的Message一样,提供两种通知方式,Notify和Record。其中Record方式稍有不同,在调用GetMsgData时需要传入两个参数MessageCode和CBaseMessage的指针,当GetMsgData返回为ture时框架会把消息拷贝到CBaseMessage的指针指向的内存中。如要没有自定义的Message只须要把中间的一行删除掉即可。

在自定义的Message的编写过程中存在bug会引起程序崩溃,所以这种方式要求用户有较高的编码和调试能力,EwayOS会在近期提供一种更高效安全的方式来解决这个问题。

编程接口说明

1) Initialize

模块初始化函数,此函数会在所有函数调用前调用,在这里填入Function运行里所需要的资源。

2) Destroy

模块销毁函数,此函数会在销毁前最后一个调用。

3) CheckMsgCode

获取Sensor消息处理方式。获取本模块对传入消息处理方式。返回值可选择方式如下:MsgProcCode_Ignore, MsgProcCode_Notify, MsgProcCode_Record。

4) JobStart

初始化完后自动调入,表示Function 开始工作。

5) SetTimer

开启或关闭一个定时器。

6) ProcTimer

定时器触发通知。

7) AddChildFun

调用其它Function模块(Function动态库)。该函数可加载其它编写好的Function动态库,被调用动态库将使用此Function进程所拥有的HighLevelAI及LowLevelAI连接,获取机器人数据以及控制机器人运动。

8) SetChildParam

对已加载子Function模块发送Parameter数据。

9) SetParamStr

拼装发送至Function模块的参数字符串。

10) ProcSetFunParam

收到外部(框架或父Function)发送的Paramter。

11) PostStopCmdToAllChildFun

向所有子Function发送Close指令

12) PostStopCmdToChildFunByID

向某一子Function发送Close指令

13) FunQuit

向父Funtion发送关闭通知。

14) ProcChildFunQuit

子Function退出回调,此Function模块调用的某一子Function已运行结束。

15) ProcCloseCmd

收到父Function或框架发送的关闭指令。

16) RequestFeature

向HighLevelAI发送消息通知请求。发送此命令应在HighLevelAI上线后。

17) ProcVoiceMsg

收到语音识别消息回调

18) ProcVisionObj

收到物体识别消息回调

19) ProcVisionMarker

收到Marker识别消息回调

20) ProcVisionFace

收到人脸识别或检测消息回调

21) ProcObstMsg

收到障碍检测消息回调

22) ProcArmPos

收到手臂移动消息回调

23) ProcRobPos

收到位置移动消息回调

24) ProcHeadPos

收到头部移动消息回调

25) ProcSystemError

收到机器人错误状态

26) GetMsgData

当CheckMsgCode返回MsgProcCode_Record时,消息数据会被记录,调用GetMsgData可返回最新一次记录的数据。

27) ProcFeatureStatus

HighLevel中Feature状态改变通知。此消息一般由Sensor状态改变触发。

28) ProcAuthChanged

LowLevelAI发送的肢体控制权变化。

29) ProcMotCmdDone

Function发送的肢体命令已响应完毕,肢体运动结束。

30) SendSpeakerPlayText

发送SpealerPlayText指令至LowLevelAI,机器人将运行Text To Speech模块进行语音转换并播放。

31) SendSpeakerPlayFile

发送SendSpeakerPlayFile指令至LowLevelAI,机器人将播放该音频文件。

32) SendHeadMove

发送SendHeadMove指令至LowLevelAI,机器人将根据指令数据移动头部。

33) SendHeadMoveSync

发送SendHeadMoveSync指令至LowLevelAI,机器人将根据指令数据移动头部

34) SendHeadStop

发送SendHeadStop指令至LowLevelAI,机器人将根据指令立刻停止头部运动。

35) SendHeadFollowTrajectory

发送SendHeadFollowTrajectory指令至LowLevelAI,机器人将根据轨迹文件进行运动。

36) SendWheelGoToPosition

发送SendWheelGoToPosition指令至LowLevelAI,机器人底盘将根据目标点进行运动。

37) SendWheelBrake

发送SendWheelBrake指令至LowLevelAI,机器人双轮立即进行减速刹车。

38) SendWheelStraight

发送SendWheelStraight指令至LowLevelAI,机器人底盘将进行位置模式的直线运动。

39) SendWheelStraightSpeed

发送SendWheelStraightSpeed指令至LowLevelAI,机器人将按指令进行直线速度运动。

40) SendWheelCycle

发送SendWheelCycle指令至LowLevelAI,机器人底盘进行位置模式的弧线运动。

41) SendWheelCycleSpeed

发送SendWheelCycleSpeed指令至LowLevelAI,机器人底盘会进行速度模式的弧线运动。

42) SendWheelTrajectory

发送SendWheelTrajectory指令至LowLevelAI,机器人底盘将按照轨迹文件进行运动。

43) SendArmFollowTrajectory

发送SendArmFollowTrajectory指令至LowLevelAI,机器人将根据轨迹文件进行手臂运动。

44) SendArmGoToAngle

发送SendArmGoToAngle指令至LowLevelAI,机器人手臂将依照指定速度运动至指定角度。

45) SendArmGoToAngleSync

发送SendArmGoToAngleSync指令至LowLevelAI,机器人手臂将依照指定时间运动至指定角度。

46) SendArmMoveGripper

发送SendArmMoveGripper指令至LowLevelAI,机器人末端执行器将以默认速度运动至指定位置。

47) SendArmStop

发送SendArmStop指令至LowLevelAI,机器人手臂将停止运动并静止在当前位置。

48) SendRecordArmTrajectory

发送SendRecordArmTrajectory指令至LowLevelAI,机器人将直线行驶。

49) SendMotorPID

发送SendMotorPID指令至LowLevelAI,机器人将直线行驶。

50) SendMotorSpeed

发送SendMotorSpeed指令至LowLevelAI,机器人肢体库电机会按指令速度进行运动。

51) PushIntoMsgList

向消息队列中插入一条消息。

Examples

FuncSDK中包含CFaceExampleCMarkerExampleCmdExampleCMsgExampleMotherFunction及KidFunction 6个example部分。分别通过源码的形式向开发者展示Function的Message机制、Feature机制、Command机制、子Function机制及Timer机制。

CFaceExample展示Message机制(MsgProcCode_Notify处理)。

CMarkerExample展示Message机制(MsgProcCode_Record处理)。

MsgExample展示Message机制中的自定义消息。

CmdExample展示Command机制。

MotherFunction及KidFunction 展示子Function机制。

Demos

Demo是一个复杂Function。当前包含FeedbackMove demo。