SSL策略框架
本文介绍SRC系统中的策略框架。
整体结构
整个结构是分层的,策略层大概可以这样分层:
- 顶层是PlayBook,负责根据场上情况来选择合适的战术。其中使用了贝叶斯方法(recursive Bayesian estimation) 来评估场上情况;
- 第二层是Play,存储着制定好的各种战术,包括各种定位球战术,运动战战术。每一个战术都是一个状态机,会根据不同的状态做出不同的动作, 满足条件时会跳出。每一个状态内部都定义了每一台机器人的行为,不过也可以选择让机器人维持之前的状态,每个状态内部还定义了机器人的角色匹配规则,在 执行这个战术(即PlayBook选择这个战术)时会根据状态内部的规则进行角色匹配。这一层主要用Lua实现;
- 第三层是Agent,在程序中代表执行动作的个体,也就是一台机器人,Play层的战术会分配给每一个机器人去分别执行。 执行战术的人选是在Play层就定好了的,在这一层将动作分配给每一个个体,个体执行分配到的任务,也就是执行SKill层的一个个动作;
- 第四层是SKill,一个SKill只定义一个机器人的动作,比如射门、传球。这一层提供各种战术动作给Play层,完成战术布置。 在这一层内部也有从简单到复杂的层级结构,最基本的SKill(动作)只有跑到一个固定点固定朝向和踢球,复杂的动作比如追踢是由调用简单的底层动作实现的。 这一层主要用C++实现;
除了策略部分之外还有一个World Model,维护着环境信息,类似于openAI gym中的environment。这个部分将摄像头和机器人身上的传感器收集到的数据暴露给 策略部分中的各个层级,为它们提供信息。这一部分有Lua和C++的接口。
有限状态机
- 进入一个状态,
- 从World Model中获取信息,判断下一步进入哪个状态
- 动作分配,
- 匹配规则
一个例子:
-- 在实现中,每个状态都是一个Lua的table类型变量,
-- 包括switch,match,Kicker、Goalie(各个角色)这些键
["run1"] = {
-- 状态的跳转函数
switch = function ()
-- 从World Model中获取信息,判断下一步进入哪个状态
if player.toTargetDist("Kicker") < 20 then
return "run2"
end
end,
-- 分配任务,调用封装的SKill
Kicker = task.goCmuRush(TargetPos1, 0),
-- 匹配规则,这样写就是不匹配
match = ""
},