文件存放位置
-
rocos/ZBin
文件夹下的CLien
与Medusa
两个可执行文件是 OpenSLL 可视化客户端的前端与后端 -
rocos/ZBin/lua_scripts
文件夹下的Config.lua
文件是配置软件运行的重要文件 -
rocos/ZBin/lua_scripts
文件夹下的play
文件夹存放的 play 代码,其中分为三个子文件夹Nor
、Ref
和Test
存放自动、裁判和测试代码 -
rocos/ZBin/lua_scripts/worldmodel
文件夹下存放我们书写 play 代码可以借助获取场上信息库函数 -
rocos/ZBin/lua_scripts/utils
文件夹下存放我们书写 play 代码可以借助的工具函数 -
rocos/ZBin/lua_scripts/skill
文件夹下存放小车执行状态时的不同的 sill 技能代码
Play 层的由来
- 1997 年 CMU STP 框架是 Skill-Tactic-Play 三层
- 2012年 ZJU 改版为 Skill-State-Play-Selector 四层
- 方便更快的更改策略
- 快速相应裁判盒节奏
- play 之间相互独立
Config.lua
文件
测试一个自己写的 play 代码需要对 Config.lua
进行下列修改:
- 将第 1 行
IS_TEST_MODE
设置为true
- 将第 13 行
gTestPlay
改为要测试的代码文件名 - 视情况而定大概指明
gRoleFixNum
用来固定某个序号的车担任某个任务 - 将测试的代码文件放入
rocos/ZBin/lua_scripts/play
中的对应文件夹并在Config.lua
文件中加入存放路径,客户端将跟踪到rocos/ZBin/lua_scripts/play
中的三个文件夹寻找对应的代码文件
存储如果是多层子文件夹分类嵌套那么就需要都写上直到执行某个代码文件
MyTestRun.lua
代码文件书写
文件结构
-
一个文件就是一个用 lua 书写的脚本代码 play 层
-
开头写明需要用到的常量,或者需要用到记录位置信息等表
-
文件中每个中括号代表一个状态
state
,帮助小车确定不同情况下需要执行的相应动作,一个 play 层包含多个state
互相跳转实现小车不同环境下实现不同的动作
state
书写
状态跳转 switch
switch=function()
函数帮助根据不同的信息确定是否需要跳转到其他 state
角色 role 与 task
Config.lua
文件中 gRoleFixNum
指明的车号就是在对应某个角色 role,只有指明的车号才能去执行任务 task,即 role 是与某个小车对应的,任务也是对应的小车执行的
- task function 对应
skill.lua
,再对应skill.cpp
- task function 内部代码只执行一遍,因为本身就是在一张表中所以表内角色任务的赋值就是一次!
但是 switch function 是表内的函数所以会执行多次,注意区分表的赋值和函数返还的区别
角色匹配 match
除去守门员应该是固定车号的,在赛场上某个任务不应该是由指定车号完成的。比如更多需要的是采取“就近原则”来完成从而实现策略的动态高效,这就需要借助 match 实现角色匹配
角色 role 与 task 指明动作后 match 写 role 的简写即可(角色对应可以去 RoleMatch.lua
文件中查看)匹配规则有三种对应三种括号:
-
{}
当前状态维持之前的匹配车号,即当前状态不重新进行角色匹配第一次执行状态时会自动匹配一个车号,所以不用担心第一次
{}
没有匹配车号的情况 -
[]
当前状态内部实时进行角色匹配 -
()
每次状态切换执行一次角色匹配,即进入状态时进行一次角色匹配并在状态内部始终维持这个角色
一个括号内可以存放多个角色即进行多个角色匹配,若是多个括号则是执行完第一个括号内的角色匹配再执行第二个括号内的角色匹配
bufcnt()
函数
不同状态跳转根据 if-else
语句直接跳转过于生硬,有时可能出现小车未执行完上一个状态就转而执行下一个状态,动作并不准确。我们可以借助 bufcnt()
函数来延迟状态的跳转从而使小车动作更加流畅
函数第一个根据判断语句的 bool 值确定是否执行,第二个参数指定当返还为 true
时延迟多少帧数执行后面的代码
例如我们想实现小车到达指定位置附近 10 cm时延迟 10 帧执行状态跳转就可以写为如下
1 | ["run1"]={ |
其中判断语句借助
player.toTargetDist('Kicker')
获取前锋到指定点的距离,同样我们还可以借助enemy.lua
、ball.lua
或者pos.lua
获取其他的信息用来状态判断
课后作业
题目:
- 没有球时让小车处于
(0,0)
- 球在进攻侧
x>0
时靠近某个进攻位置 - 球在防守侧
x<0
时靠近某个防守位置 - 利用
bufcnt()
使程序运行更加稳定
分析:
- 借助一个
check()
函数判断小球在场的合法性 - 设立三个
state
分别为outside
、forward
和backword
- 状态跳转注意判断条件考虑齐全,跳转到
forward
和backword
首先是必须小球在场合法然后才是判断到达攻防侧侧,否则直接考虑第二个那么小球在场外是小车到达(0,0)
会紧接着又跑到攻防侧从而进入死循环 - 小球几乎跑全场所以
bufcnt
设置帧数大一些尽可能避免小车出现漂移 - 匹配前锋进行攻防不能进入禁区
代码:
1 | local testPos={ --confirm the positions of three state |