编程指南
使用bitbot框架编写的机器人软件系统具备相同的编程接口。
运行流程
程序运行被分为三个阶段,配置->状态循环->结束,配置和结束阶段的任务仅被执行一次,使用者通过注册相应的回调函数实现对应功能。状态循环中进行事件处理和状态转移。
状态机
机器人任务执行流程完全依赖于状态机。状态中包含程序将执行的行为,事件的发生意味着将要改变数据或状态。
用户通过RegisterEvent
和RegisterState
函数,将自定义event和state注入内核中。
event 事件
事件处理函数
using EventFunc = std::function<std::optional<StateId>(bitbot::EventValue value, UserData& user_data)>;
参数
value
:事件值
user_data
:用户数据
返回值
std::optional<StateId>
:要转移的下一个状态
事件处理函数的返回值使用std::optional
包装,意味着事件可以选择性发生状态转移,即事件可以仅改变某些数据而不引起状态变化。
注册事件
void RegisterEvent(std::string name, bitbot::EventId id, bitbot::EventFunc func, bool always_enabled = false)
参数
name
:事件名称
id
:事件唯一标识,用户注册的事件id应大于1000
func
:事件处理函数
always_enabled
:事件是否对所有状态均启用
kernel内置事件
enum class KernelEvent : EventId
{
STOP,
START,
ENABLE_RECORD,
};
STOP
停止运行,对所有状态生效
START
转移至用户定义的第一个状态
ENABLE_RECORD
启用日志记录功能
state 状态
状态行为函数
using StateFunc = std::function<void(const bitbot::KernelInterface& kernel, bitbot::ExtraData& extra_data, UserData& user_data)>;
参数
kernel
:kernel接口
extra_data
:额外数据
user_data
:用户数据
注册状态
void RegisterState(std::string name, bitbot::StateId id, bitbot::StateFunc func, std::vector<uint32_t> events)
参数
name
:事件名称
id
:状态唯一标识,用户注册的状态id应大于1000
func
:状态行为函数
events
:该状态可响应的事件
SetFirstState 设置首个状态
用户将定义多个状态,程序无法得知将首先从哪个状态开始运行,需要用户手动指定。
void SetFirstState(StateId id);
参数
id
:状态id
kernel内置状态
enum class KernelState : StateId
{
IDLE,
};
IDLE
空闲等待
ConfigFunc 配置函数
程序启动并完成初始化后,将执行用户配置函数,用于执行用户的初始化任务。该函数仅被调用一次。
配置函数类型定义
using ConfigFunc = std::function<void(const BusManagerT & bus, UserData& user_data)>;
参数
bus
:当前软件框架使用的总线管理器
user_data
:用户数据
注册函数
void RegisterConfigFunc(ConfigFunc func);
仅允许注册一个配置函数,后注册的将覆盖前一个。
FinishFunc 结束函数
任务循环停止后程序进入结束阶段,该函数仅运行一次,然后程序退出。
结束函数类型定义
using FinishFunc = std::function<void(UserData&)>;
参数
UserData
:用户数据
注册函数
void RegisterFinishFunc(FinishFunc func);
仅允许注册一个结束函数,后注册的将覆盖前一个
ExtraData 额外数据
使用者可添加数据(仅限数字)至系统中,实现在界面显示与本地文件记录。
数据标头是Kernel的模板参数之一,无法在运行时添加新的数据标头。
对ExtraData的使用可以通过以下三种方式
// 使用顺序进行索引
extra_data[0] = 1; // 将索引作为[]运算符参数
extra_data.Set<0> = 1; // 将索引作为模板参数
// 使用标头进行索引
extra_data.Set<"time"> = 1; // 将索引作为模板参数
UserData 用户数据
该项是用户自定义的数据类型,通过模板参数传入kernel,生命周期覆盖程序运行的全部时间。用户将在Config函数、Finish函数、事件处理函数、状态行为函数中获得其访问接口。
KernelInterface 运行时接口
运行时接口是状态行为函数与kernel交互的唯一途径。
EmitEvent 触发事件
程序运行过程中用户可手动触发事件。
void EmitEvent(EventId id, EventValue value);
参数
id
:事件id
value
:事件值