如何编写编译Robocup3D代码
开始编写球队代码
装好了Robocup 3D比赛平台后,就要开始着手编写球队策略代码了。
我们使用的是utaustinvilla的Robocup 3D球队代码,球队的体态运动等都已经是别人写好的,我们暂时不要研究。
在下图中,behaviors文件夹下的strategy.cc文件,就是我们需要编写策略代码的部分。

void NaoBehavior::beam()
球队上场阶段的函数,这一部分代码来确定球队如何上场,最开始的上场的站位在这里编写。通过if语句判断球员编号,根据球员编号返回(x坐标,y坐标,面向角度)。
这里正好提一下,球场是一个30*20的绿茵场,以中心为坐标原点。满足x∈[-15,15],y∈[-10,10]。
//1号球员站位
if(worldModel->getUNum()==1){
    beamX= -HALF_FIELD_X + 1;//x坐标
    /* -HALF_FIELD_x = 15 代表半场的x轴距离
    等价于 beamX=-15+1即-14 */
    beamY = 0;//y坐标
    beamAngle = 0;//面向角度,0为向右,90向上,以此类推
}
//2号球员站位
if(worldModel->getUNum()==2){
    beamX= -HALF_FIELD_X +2;
    beamY = 0;
    beamAngle = 0;
}
//3~11号球员站位以此类推
SkillType NaoBehavior::PlayOnSkill()
球队上场后,按下K键开球。之后球队先执行开球函数MyKickOff()或OppKickOff(),然后就会开始执行PlayOnSkill()这一段函数,这也是我们目前主要要编写部分。你们目前看到的这部一部分函数是学长上次比赛写的,其中部分代码有英文注释。之后我会另写一篇blog,对这一部分代码详细注释。
这里给出已知的功能函数(这里列出的并非全部,有待补充):
| 功能 | 函数 | 
|---|---|
| 获取球员编号 | worldModel->getUNum() | 
| 动作踢球 | SkillType kickBall(kickTypeToUse,VecPosition &target); | 
| 设置及坐标参数返回 | VecPosition(x,y,0) | 
| 判断球员于目标距离 | temp.getDistanceTo(VecPosition(x,y, 0) | 
| 获取当前球员坐标 | getMyPosition() | 
| 获取当前对象的指定坐标 | temp.getX()(之前必须在前重新定义对象) | 
| 获得指定球员坐标 | worldModel->getTeammate(i)(i为我方球员编号) | 
| 指定当前球员行动方向 | SkillType goToTargetRelative(/相对球员方向/,/角度/) | 
| 获取比赛时间 | getGameTime() | 
| 获取比赛状态 | getPlayMode() | 
(这部分功能函数不止可以写在PlayOnSkill()函数里,在开球、罚球函数里均可调用。)
其他阶段函数
比赛的正常流程下有许多比赛状态,大概流程如下:
| 比赛状态 | 函数 | 
|---|---|
| 球员上场 | beam() | 
| 开球策略 | MyKickOff()、OppKickOff() | 
| 主要策略 | PlayOnSkill() | 
| 罚球策略 | KickIn、CornerKick、GaolKick、FreeKick | 
所有策略函数注释如下
/*  正常比赛  */
void beam();				//球队上场
SkillType MyKickOff();		//我方开球
SkillType OppKickOff();		//对方开球
SkillType PlayOnSkill();	//常规策略
/*  罚球函数  */
SkillType MyKickIn();		//我方界外球
SkillType OppKickIn();		//对方界外球
SkillType MyCornerKick();	//我方角球
SkillType OppCornerKick();	//对方角球
SkillType MyGaolKick();		//我方球门球
SkillType OppGaolKick();	//对方球门球
SkillType MyFreeKick(); 	//我方任意球
SkillType OppFreeKick();	//对方任意球
注意在下图的代码中有一段selectSkill()函数,是这段函数将比赛阶段与对应的策略函数对应。例如,worldModel->getPlayMode()== PM_PLAY_ON时,返回return PlayOnSkill()函数。

比赛开始,先是阶段执行beam(),然后开球极阶段执行MyKickOff()或者OppKickOff(),球离开中圈后进入策略阶段执行playOnSkill()。当满足界外球、角球、球门球的情况下,执行相应函数。(对这三种情况不了解的可自行百度。)
修复make异常
这里要注意的是,我们从学长那里拿到代码是不能直接make的。
我们打开终端,cd到球队代码目录下(utaustinvilla3d-master),输入make指令进行编译。第一次你可能会看到如下报错结果:
因为这是从学长电脑拷贝给你们的,你们这个文件的目录和学长文件目录可能不一样。就算同样是放在桌面,如果是中文系统就是/home/用户名/桌面,英文就是/home/用户名/Desktop,而且我们用户名肯定也不一样。所以目录基本上是一定不一样。
那就必须改目录!

CMakeFiles下面有很多文件里都存储有项目的目录,为了能运行,都要修改。主要是要修改CMakeFiles/newforces.dir/下面的文件,然后退回到CMakeFile一级,还有一两个文件需要修改。

修改时利用sublime编辑器,上面的find-Replace进行全部替换。

这张图中,我将所有的 桌面 一键替换成了 Desktop。那么你的用户名也和我不一样,那你们就应该是 Shiraka/桌面替换成你的用户名/Desktop。确保替换后,和你的目录一致就行了。
最后成功运行如下图:


如果不一样,依旧报错,说明还是有地方没改。再仔细检查一下CMakeFile下有没有漏网之鱼。
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号