为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

机器人足球仿真实验报告

2019-02-18 22页 doc 55KB 142阅读

用户头像

is_281650

暂无简介

举报
机器人足球仿真实验报告合肥工业大学计算机与信息学院机器人足球仿真实验报告 班级:计算机科学与技术11-1 班姓名:魏慷学号:20112425 2012 年12 月 5 日 1 实验一机器人足球比赛编程预备知识 1. 实验目的 掌握RoboCup 仿真机器人足球比赛相关知识点,具体内容如下:(1) Linux 操作系统的熟悉及了解其基本操作。(2) 掌握Linux 下如何进行C++编程,了解gcc 编译器以及一些简单编辑工具,如:vi、emacs、gedit、Anjuta、Kdevelope 等。(3) 启动RoboCup 仿真(2D)足...
机器人足球仿真实验报告
合肥工业大学计算机与信息学院机器人足球仿真 班级:计算机科学与技术11-1 班姓名:魏慷学号:20112425 2012 年12 月 5 日 1 实验一机器人足球比赛编程预备知识 1. 实验目的 掌握RoboCup 仿真机器人足球比赛相关知识点,具体内容如下:(1) Linux 操作系统的熟悉及了解其基本操作。(2) 掌握Linux 下如何进行C++编程,了解gcc 编译器以及一些简单编辑工具,如:vi、emacs、gedit、Anjuta、Kdevelope 等。(3) 启动RoboCup 仿真(2D)足球队的比赛。2. 实验设备 硬件环境:PC 机软件环境:操作系统linux 3. 实验内容 (1) 掌握Linux 一些常用的命令 文件或目录处理格式:ls [-atFlgR][name] 第一项是一些语法加量。第二项是文件名。常用的方法有:ls 列出当前目录下的所有文件。ls –a 列出包括以.开始的隐藏文件的所有文件名。ls –t 依照文件最后修改时间的顺序列出文件名。ls –F 列出当前目录下的文件名及其类型。以/结尾示为目录名、以* 结尾表示未可执行文件、以@结尾表示为符号连接。ls –l 列出目录下所有文件的权限、所有者、文件大小、修改时间及名称。ls –lg 同上,并显示出文件的所有者工作组名。ls –R 显示出目录下以及其所有子目录的文件名。 改变工作目录格式::cd [name] name :目录名、路径或目录缩写。常用的方法有:cd 改变目录位置至用户登录时的工作目录。cd dirl 改变目录位置至dirl 目录下。cd ~user 改变目录位置至用户的工作目录。cd .. 改变目录位置至。cd ../user 改变目录位置至相对路径user 的目录下。cd /../.. 改变目录位置至绝对路径的目录位置下。 复制文件格式:cp [-r] 源地址目的地址 2 常用的方法有:cp file1 file2 将文件file1 复制成file2 cp file1 dir1 将文件file1 复制到目录dir1 下,文件名仍为file1。cp /tmp/file1 将目录/tmp 下的文件file1 复制到当前目录下,文件名仍为file1。cp /tmp/file1 file2 将目录/tmp 下的文件file1 复制到当前目录下,文件名仍为file2。cp -r dir1 dir2 复制整个目录。 移动或更改文件、目录名称格式:mv 源地址目的地址常用的方法有:mv file1 file2 将文件file1 更名为file2。mv file1 dir1 将文件file1 转移到目录dir1 下,文件名仍为file1。mv dir1 dir2 将目录dir1 更改为目录dir2。 建立新目录格式:mkdir 目录名删除目录格式:rmdir [目录名|文件名] 常用的方法有:rm –r dir1 删除目录dir1 及其子目录下的所有文件。 列出当前所在的目录位置格式:pwd 查看文件内容格式:cat 文件名 文件权限的设定格式:chmod [-R] mode name name:文件名或目录名。mode:3 个或8 个数字或rwx 的组合。r-read(读权限)、w-write(写权限)、x-execute(执行) 常用的方法有:chmod 777 file1 给所有用户file1 全部的权限。 文件的打包和解压缩格式:tar [option] [file] gzip[option] [file] tar 主要来进行打包而不压缩,而gzip 则进行压缩。option 主要有:-c —创建一个新归档。-f —当与-c 选项一起使用时,创建的tar 文件使用该选项指定的文件名;当与-x 选项一起使用时,则解除该选项指定的归档。-t —显示包括在tar 文件中的文件列表。-v —显示文件的归档进度。-x —从归档中抽取文件。-z —使用gzip 来压缩tar 文件。如使用:tar -cvf filename.tar /home/mine/work /home/mine/school 上面的命令把/home/mine 目录下的work 和school 子目录内的所有文件 3 都放入当前目录中一个叫做filename.tar 的新文件里。(2) 完成以下操作: 1. 如何找到用户主目录的绝对路径名?在自己的系统上,用户主目录的绝对路径名是什么? 执行cd;执行pwd;即显示用户主目录的绝对路径名。用户主目录的绝对路径名是”/home/username” 2. 将当前工作目录从/home/UV A 转到/home/Tsinghua 需要使用什么命令? 如何显示当前目录? cd /home/Tsinghua 或 cd ../Tsinghua 3. 如何在当前目录下建立子目录RoboCup? mkdir Robcup 4. 如何删除子目录RoboCup? rmdir Robcup 5. 如何查看当前目录下的内容? ls 6. 如何将文件start.sh 的权限设定为:start.sh 属于可读、可写、可执行? 可读:chmod g+rr start.sh 可写:chmod g+rw start.sh 可执行: chmod g+rx start.sh 7. 如何将当前目录包括所有子目录全部做备份文件,备份文件名为first.tar? tar czvf first.tar dir1 8. 如何将目录/home 下每一个文件压缩成.gz 文件? tar -cvf store.tar dir1 9. 如何把上例中每个压缩的文件解压,并列出详细的信息? tar xvf store.tar ls -lg 4. 启动球队上场比赛 完成以下操作:rcssserver rcsslogplayer 在球队路径下:./start.sh 在本地启动第二个球队:./start.sh localhost aaa 实验二Demeer5 基本动作1 1. 实验目的 (1) 了解Demeer5 的工作原理 4 (2) 学会对Demeer5 进行简单的修改2. 实验设备 硬件环境:PC 软件环境:Linux 3. 实验内容 (1) Demeer5 的工作原理:Demeer5 函数是整个球队的核心,它最终返回一个可以执行的动作,底层的模块负责将此动作发送给server,然后由server 执行。可以说,Demeer5 就是我们想法的体现,是一支球队的大脑。在Demeer5 中有一系列的判断来决定每个周期的动作。下面对Demeer5 进行简要的. Demeer5()是一个决策函数,在策略上使用的是下面这个简单的策略:如果球可踢,则用最大力量踢球;如果球不可踢且我是队友中最快到球的队员,则去截球;其他情况按战略点跑位。我们现在只要看一下球可踢时的代码:else if( WM->isBallKickable()) // 如果球可踢 { //确定踢向的点 VecPosition posGoal( PITCH_LENGTH/2.0, -1+2*(WM->getCurrentCycle()%2))* 0.4 * SS->getGoalWidth() ); //调用踢球的动作 soc = kickTo( posGoal, SS->getBallSpeedMax() ); // kick maximal //将动作放入命令队列中 ACT->putCommandInQueue( soc ); //将脖子转向球 ACT->putCommandInQueue( turnNeckToObject( Object_BALL, soc ) ); //调试信息 Log.log( 100, "kick ball" ); } 这一小段函数决定了当球在球员Agent 的可踢范围之内时应当做的动作,这里是一个简单的把球向前踢而不考虑任何其他情况的方法。该程序段的条理是很清晰的。 5 (2) 对Demeer5 进行简单的修改:现在我们对Demeer5 进行简单的修改,让它在球可踢的时候进行带球的动作。带球就是kick 和dash 动作序列的结合。带球的函数在BasicPlayer 中,函数为dribble().它接收两个参数,第一个参数为带球的方向,第二个参数为带球的类型。带球类型解释如下:DRIBBLE_FAST:快速带球;DRIBBLE_SLOW:慢速带球;DRIBBLE_WITHBALL:安全带球;所以,对dribble 的一种调用形式为:dribble(ang,DRIBBLE_FAST )其中ang 为AngDeg(是一个double)类型该函数的返回值是一个SoccerCommand 类型。知道了如何调用dribble,我们来对Demeer5 进行替换:else if( WM->isBallKickable()) { AngDeg ang = 0.0; soc = dribble(ang,DRIBBLE_FAST ); // 进行带球 //将动作放入命令队列中 ACT->putCommandInQueue( soc ); //将脖子转向球 ACT->putCommandInQueue( turnNeckToObject( Object_BALL, soc ) ); //记录调试信息 Log.log( 100, "kick ball" ); } 这样,在球可踢的时候,球员智能体将把球带向前方,这里取的是0 度角,即沿x 轴一直向前快速带球。我们再次对Demeer5 函数进行修改,这次是让球员Agent 将球踢向各个不同的地方。这将调用kickTo()函数来完成。下面简要说明一下kickTo ()函数的使用方法:这个函数有两个参数,第一个参数是目标点的坐标,第二个参数是球到达目标点是的速度,返回一个踢球的动作。可以使用下面的形式来调用:VecPosition pos( x, y ); double Speed = 1.0; kickTo( pos , Speed ); kickTo()函数在其内部将会决定踢球时所用力量的大小,并且会判断是否能够将球踢到该点,并作出相应的调整。比如,将球一直踢向(0,0)点, 1.0 的末速度:else if( WM->isBallKickable()) { soc = kickTo( VecPosition( 0, 0 ),1.0); 6 //将动作放入命令队列中 ACT->putCommandInQueue( soc ); //将脖子转向球 ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); //记录调试信息 Log.log( 100, "kick ball" ); } (3) 根据上述操作,完成以下踢球操作:将球踢向对方的球门。VecPosition pos=WM->getPosOpponentGoal; soc=kickTo( pos,1.0 ); ACT->putCommandInQueue ( soc ); ACT->putCommandInQueue ( turnNeckToObject ( OBJECT_BALL, soc ) ); 将球踢向距离自己最近的队友。ObjectT o=WM->getClosestInSetTo( OBJECT_SET_TEAMMATES,posAgent); soc=kickTo( WM->getGlobalPosition( o ) ,1.0 ); ACT->putCommandInQueue ( soc ); ACT->putCommandInQueue ( turnNeckToObject ( OBJECT_BALL, soc ) ); 尝试不同的踢球点。(略) (4) 根据上述内容,完成以下带球的操作:用不同的带球模式进行带球,并观察效果,比较异同。AngDeg ang = 0.0; soc = dribble(ang,DRIBBLE_SLOW); ACT->putCommandInQueue( soc ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); 将球向对方的球门方向带。double ang=( VecPosition(52.5,0)-posAgent).getDirection();//求与球门间角度 soc=dribble( ang,DRIBBLE_SLOW ); ACT->putCommandInQueue( soc ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); 尝试不同的带球组合。(略) (5) 根据上述内容,完成以下综合练习:带球与踢球的结合:让agent 一直向对方球门的方向带球,在进入对方禁区后以最大力量踢向球 7 门( 末速度最大为2.7 )。涉及到的具体函数请查看教材。VecPosition posGoal ( 52.5 , 0 ); if ( WM->isInTheirPenaltyArea ( WM->getBallPos() ) ) //判断是否在对方禁区 { soc=kickTo ( posGoal , 2.7 ); } else { double ang=( posGoal - posAgent ).getDirection();//求与球门间角度 soc=dribble( ang,DRIBBLE_FAST ); } ACT->putCommandInQueue( soc ); ACT->putCommandInQueue( turnNeckToObject( Object_BALL, soc ) ); 实验三Demeer5 基本动作2 1. 实验目的 熟悉demeer5 并学会demeer5 的基本使用方法,具体内容如下:(1) 能理解UVA 程序中原来的demeer5 中的内容(2) 能通过修改demeer5 中的具体函数内容实现对场上球员的控制(3) 能通过底层动作的简单组合控制场上队员做出一些复杂动作 2. 实验设备: 硬件设备:pc 机软件设备:操作系统linux 3. 实验内容 (1) 在球队程序中找到playerTeams.cpp; (2) 在player.cpp 中找到demmer5 函数; (3) 阅读此段程序,并结合Monitor 观察球员的具体行为(你将发 现可以踢到球的球员会将球朝球门的方向踢去,而不能踢到球的 队员中如果是离球最近的队员就去截球,否者则按阵型跑位); (4) 修改demmer5 函数改变队员的行为具体步骤如下:①在demeer5 函数中找到 8 if( WM->isBallKickable()) // isBallKickable()函数用来判断球是否可踢 { VecPosition posGoal( PITCH_LENGTH/2.0, (-1 + 2*(WM->getCurrentCycle()%2)) * 0.4 * SS->getGoalWidth() ); //设定射门位置坐标 soc = kickTo( posGoal, SS->getBallSpeedMax() ); // 朝球门方向将球以最大 力度踢出 ACT->putCommandInQueue( soc ); //只有把命令放入命令队列动作才会执行 ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); //做动作的同时改变脖子的方向 } ②『控球』将此函数修改为if( WM->isBallKickable()) { soc = kickBallCloseToBody(45);//45 是踢球的方向 ACT->putCommandInQueue( soc ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } 然后编译运行程序,观察球员的行为我们会发现当球可踢时,球员不再朝着球门的方向踢了,而是将球绕自己身体转动(uva 的这个底层动作经常把球转丢!)③『带球』将此函数修改为if( WM->isBallKickable()) { soc = dribble(0.0,DRIBBLE_SLOW);//其中dribble 函数中第一个参数表示带球的 方向-180~180 之间,不一定是0.0 ACT->putCommandInQueue( soc ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } 后编译运行程序,观察球员的行为我们会发现当球可踢时,球员不再朝着球门的方向踢了,而是朝我们指定的方向执行带球 9 ④『传球』将此函数修改为if( WM->isBallKickable()) { soc = leadingPass(Object_TEAMMATE_9,1);//9 是接球的人,1 是指球与接球人 之间的距离 //其中leadingPass 中第一个参数表示传球的对象,本实验中我们将球直接传给指定 号码(1~11)的球员,不一定是Object_TEAMMA TE_9 ACT->putCommandInQueue( soc ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } 然后编译运行程序,观察球员的行为我们会发现当球可踢时,球员不再朝着球门的方向踢了,而是将球传给我们指定号码的队员。 ⑤『配合』将此函数修改为if( WM->isBallKickable()) { if(WM->getAgentObjectType()==OBJECT_TEAMMATE_9) soc = dribble(0.0,DRIBBLE_SLOW); //带球 } else soc = leadingPass(OBJECT_TEAMMATE_9,1); //传球 ACT->putCommandInQueue( soc ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } 编译程序,观察球员行为,我们会发现,当9 号队员得到球后会朝前方带球,其他队员得到球后会将球传给9 号(不管9 号是不是越位). (5) 根据以上描述完成以下实验内容:如果在对方禁区内就射门,否则,如果是7,8,9 号队员就朝前带球,其他队员将球传给9 号(用WM->isInTheirPenaltyArea(WM->getBallPos()) 来判断球是否在对方禁区)如果队员的位置在自己半场就将球朝对方球门踢去,否者就朝前方带球(用WM->getBallPos().getX()来得到球的x 坐标)当有人来抢球时(离自己很近),就将球传给离自己最近的队员,否则就自己带球(调用WM->getClosestRelativeInSet 函数来得到离自己最近的己方或对方球员,通过pos1.getDistanceTo(pos2)来得到两位置之间的距离)。Circle cir ( posAgent,2.0 ); //定义这样一个圆形区域,以我为圆心,2.0 为半径 10 int num=WM->getNrInSetInCircle ( OBJECT_SET_OPPONENTS,cir ); //判断2.0 范围内有多少人 if ( num>0 ) { soc=leadingPass( WM->getClosestRelativeInSet( OBJECT_SET_TEAMMATES ) ,1); } else if ( WM->getBallPos().getX() >0 ) { if ( WM->isInTheirPenaltyArea ( WM->getBallPos() ) ) { VecPosition posGoal ( PITCH_LENGTH/2.0, ( -1+2* ( WM->getCurrentCycle() %2 ) ) *0.4*SS->getGoalWidth() ); soc=kickTo ( posGoal,SS->getBallSpeedMax() ); } else if ( WM->getAgentObjectType() ==OBJECT_TEAMMATE_7 || WM->getAgentObjectType() ==OBJECT_TEAMMA TE_8 || WM->getAgentObjectType() ==OBJECT_TEAMMATE_9 ) { soc=dribble ( 0.0,DRIBBLE_SLOW ); } else { soc=leadingPass ( OBJECT_TEAMMATE_9 ,1 ); } } else { VecPosition pos= ( PITCH_LENGTH/2.0, ( -1 + 2* ( WM->getCurrentCycle() %2 ) ) * 0.4 * SS->getGoalWidth() ); soc=kickTo ( pos,SS->getBallSpeedMax() ); } ACT->putCommandInQueue ( soc ); // 放入命令队列 ACT->putCommandInQueue ( turnNeckToObject ( OBJECT_BALL, soc ) ); 11 实验四复杂的动作决策 1. 实验目的 进一步了解demeer5并能熟悉的修改demeer5的内容以达到对场上的球员的控制(1) 能理解UV A 程序中原来的demeer5 中的全部内容(2) 能通过修改demeer5 中的具体函数内容实现对场上球员的控制(3) 能通过底层动作的简单组合控制场上队员做出一些复杂动作决策(4) 对WorldModel 有初步的认识,学会在WorldModel,basicplayer 里添加新函数2. 实验设备 硬件环境:PC 软件环境:操作系统linux 3. 实验内容 (1) 在球队程序中找到player.c 并打开; (2) 在player.c 中找到demmer5 函数; (3) 阅读此段程序,并结合monitor 观察球员的具体行为(你将发 现可以踢到球的球员会将球朝球门的方向踢去,而不能踢到球的 队员中如果是离球最近的队员就去截球,否者则按阵型跑位); (4) 修改demmer5 函数改变队员的行为具体步骤如下:①在demeer5 函数中找到else if( WM->getFastestInSetTo( Object_SET_TEAMMATES, OBJECT_BALL, &iTmp )` == WM->getAgentObjectType() && !WM->isDeadBallThem() ) { // 如果是最快到达球的队员 Log.log( 100, "I am fastest to ball; can get there in %d cycles", iTmp ); soc = intercept( false ); // 截球 if( soc.commandType == CMD_DASH && // 当体力低时 WM->getAgentStamina().getStamina() < SS->getRecoverDecThr()*SS->getStaminaMax()+200 ) 12 { soc.dPower = 30.0 * WM->getAgentStamina().getRecovery(); // 慢速移 动 ACT->putCommandInQueue( soc ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); // 脖子转向球 } else // 当体力高时 { ACT->putCommandInQueue( soc ); //正常移动速度 ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );// 脖子转向球 } } 此函数的内容是,当球不可踢时,如果是离球最近的队员就执行截球命令(截球函数intercept()在BasicPlayer.c 中定义)观察在队员体力值小于多少时,带球速度会变慢。②现在我们来通过修改函数,来改变非持球队员的决策,在以上函数之前加上此段代码:else if(WM->getAgentObjectType()==OBJECT_TEAMMA TE_9) //如果是9 号队员 { soc = SoccerCommand(CMD_TURN,60); //转身体 ACT->putCommandInQueue( soc ); ACT->putCommandInQueue( alignNeckWithBody( ) ); //脖子随着身体一起转动 } 然后编译运行程序,观察球员的行为我们会发现当9 号不持球时,身体在一直的转动(此动作可用来找球) (5) 在WorldMoled 里填加状态函数①.打开WorldModel.h,在里面预定义函数,即写入bool isOpponentAtAngleEx( AngDeg angA , AngDeg angB ,double dDist ); 该函数用来判断当前球员角度在angA~angB 之间距离小于dDist 的范围内是 13 否有对方队员。 ②.找到并打开WorldModel.c 在里面填加一个新函数bool WorldModel::isOpponentAtAngleEx( AngDeg angA , AngDeg angB ,double dDist ) { VecPosition posAgent = getAgentGlobalPosition(); VecPosition posOpp; AngDeg angOpp; int iIndex; for( ObjectT o = iterateObjectStart( iIndex, OBJECT_SET_OPPONENTS ); o != OBJECT_ILLEGAL; o = iterateObjectNext ( iIndex, OBJECT_SET_OPPONENTS ) ) { posOpp = getGlobalPosition( o ); angOpp = ( posOpp - posAgent ).getDirection() ; if( angA<=angOpp && angOpp <=angB && posAgent.getDistanceTo( posOpp ) < dDist ) return true; } iterateObjectDone( iIndex ); return false; } ③.将if( WM->isBallKickable())内的内容改为: if( WM->isBallKickable()) { double ang = (VecPosition(52.5,0)-posAgent).getDirection(); if ( WM->isOpponentAtAngleEx(ang-45, ang, 6) ) ang+=45; else if ( WM->isOpponentAtAngleEx(ang,ang+45,6) ) ang-=45; SoccerCommand soc = dribble ( ang , DRIBBLE_SLOW ); ACT->putCommandInQueue( soc ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } 然后编译运行程序,观察球员的行为,试分析球员的行为 14 (6) 根据以上描述完成练习:通过基本动作的组合实现球员的以下 行为判断守门员的位置,朝球门空隙较大的一方射门,(通过在WorldModel 里建立新状态来判断,球门哪一方空隙较大,守门员的位置为VecPosition posGoalie = WM->getGlobalPosition(WM->getOppGoalieType());球门位置坐标为(52.5,0),可尝试朝(52.5, 6.5)(52.5,-6.5)两点射门)VecPosition vec=WM->getGlobalPosition(WM->getOppGoalieType()); if(vec.getY()>0) { V ecPosition pos=(52.2,-6.5); soc=kickTo(pos,SS->getBallSpeedMax()); } else { VecPosition pos1=(52.5,6.5); soc=kickTo(pos1,SS->getBallSpeedMax()); } ACT->putCommandInQueue( soc ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc )); 在BasicPlay 里填加一个带球函数,要求如果无人阻挡(带球将要经过的路线附近没有对方球员)就朝球门方向带球,否则想办法避开对方球员带球前进(要求只要作出闪避的动作即可,不要求效果)。打开WorldModel.h,在里面预定义函数,即写入bool isOpponentAtAngleEx( AngDeg angA , AngDeg angB ,double dDist ); 该函数用来判断当前球员角度在angA~angB 之间距离小于dDist 的范围内是否有对方队员。找到并打开WorldModel.c 在里面添加一个新函数:bool WorldModel::isOpponentAtAngleEx( AngDeg angA , AngDeg angB ,double dDist ) { VecPosition posAgent = getAgentGlobalPosition(); VecPosition posOpp; AngDeg angOpp; int iIndex; for( ObjectT o = iterateObjectStart( iIndex, OBJECT_SET_OPPONENTS ); o != OBJECT_ILLEGAL; o = iterateObjectNext ( iIndex, OBJECT_SET_OPPONENTS ) ) { posOpp = getGlobalPosition( o ); angOpp = ( posOpp - posAgent ).getDirection() ; 15 if( angA<=angOpp && angOpp <=angB && posAgent.getDistanceTo( posOpp ) < dDist ) return true; } iterateObjectDone( iIndex ); return false; } 在playerteams.cpp 中添加else if( WM->isBallKickable()) { Circle cir(posAgent,2.5); int num=WM->getNrInSetInCircle(Object_SET_OPPONENTS,cir); if(num<2) { double ang = (VecPosition(52.5,0)-posAgent).getDirection(); if ( WM->isOpponentAtAngleEx(ang-45, ang, 6) ) ang+=45; else if ( WM->isOpponentAtAngleEx(ang,ang+45,6) ) ang-=45; SoccerCommand soc = dribble ( ang , DRIBBLE_SLOW ); } else { soc=dribble(0.0,DRIBBLE_FAST); } ACT->putCommandInQueue( soc ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc )); } 尝试修改视觉函数使得球员能更多的获得场上信息(要求不影响球员的动作)。先在Basicplayer.h 中函数声明SoccerCommand view1122333 (SoccerCommand soc ); 在Basicplayer.cpp 中view1122333 (SoccerCommand soc )函数定义如下:/*将视觉分成1122333 的视觉模式(“1”代表60 度,“2”代表120,“3”代表180)*/ SoccerCommand BasicPlayer::view1122333(SoccerCommand soc) { //7 --> 共分成7 份 VecPosition posAgent = WM->getAgentGlobalPosition(); AngDeg angBody = WM->getAgentGlobalBodyAngle(); AngDeg angTurn=30; switch( WM->getCurrentCycle()%7 ) { 16 case 0: angTurn -= 60; case 1: ACT->putCommandInQueue(SoccerCommand(CMD_CHANGEVIEW, V A_NARROW, VQ_HIGH)); ACT->putCommandInQueue(turnNeckToPoint(posAgent+VecPosition( 5, VecPosition::normalizeAngle(angBody+angTurn), POLAR), soc)); break; case 2: case 3: ACT->putCommandInQueue(SoccerCommand(CMD_CHANGEVIEW, V A_NORMAL, VQ_HIGH)); ACT->putCommandInQueue(turnNeckToPoint(posAgent+VecPosition(5, angBody, POLAR), soc)); break; case 4: case 5: case 6: ACT->putCommandInQueue(SoccerCommand(CMD_CHANGEVIEW, V A_WIDE, VQ_HIGH)); break; default:; } } 再在playerTeams.cpp 球可踢的条件下增加ACT->putCommandInQueue(view1122333(soc)); 就可看到明显的视觉变化。 实验五特殊比赛模式的设计 1. 实验目的 掌握Robocup 仿真机器人足球比赛中特殊比赛模式发生的条件;掌握Robocup 仿真机器人足球比赛特殊比赛模式的规则要求;了解Robocup 仿真机器人足球比赛特殊比赛模式的战术设计思想;进一步熟悉WorldModel 类。 2. 实验设备 硬件环境:PC 机软件环境:操作系统Linux 17 3. 实验内容 (1) 概述Robocup 仿真机器人足球比赛特殊比赛模式包括角球(corner_kick)、界外球(kick_in)、定位球/任意球(free_kick)以及球门球(goal_kick)。(2) 角球(corner_kick)当防守方球员将球踢出底线时,由进攻方开角球。Server 一旦接收到发球队员发出的kick 命令后,就将比赛模式设为正常的play_on 模式。注意,和国际足联的规则类似,发球队员在其他球员接触球之前不能再触球,否则判犯规。此时,另一方球员须在一定时间(根据Manual 的为300 周期)内将球开出,否则算发球失误,由对方发定位球。在UV A_trilearn 的原代码中,球员是不管这些特殊比赛模式的,统统是最近的球员跑向球,一脚踢向球门。这就需要我们手工编码完成这些细节地方。一种简单的设计思路是:(1)如果比赛进入角球模式,则离球最近的球员A 跑向球,而次近的球员 B 跑到某个接应点,等待 A 将球传过来;(2)A 跑到球跟前(即进入可踢范围)时,不必立 即将球开出,可以先看看场上环境,等B 跑到预定位置并且体力恢复得差不多时再开球。以上设计思路同学们在实验过程中只须完成(1)即可,对于学有余力的同学可以考虑(2)的实现。下面列出几个可能用到的函数:PlayModeT WorldModel::getPlayMode() const 返回比赛模式(或者直接用bool WorldModel::isCornerKickUs() 判断是不是我方开角球);ObjectT WorldModel::getClosestInSetTo(ObjectSetT objectSet, ObjectT o, double *dDist=NULL, double dConfThr=-1.0) 返回在对象集合objectSet 中距离对象o 最近的对象,只有当对象的可信度高于给定的阈值才被考虑,如果没有给出阈值则使用PlayerSettings 中定义的阈值,同时dDist 返回距离; ObjectT WorldModel::getSecondClosestInSetTo(ObjextSetT objectSet, ObjectT o, double *dDist=NULL, double dConfThr=-1.0) 返回在对象集合objectSet 中距离对象o 次近的对象,只有当对象的可信度高于给定的阈值才被考虑,如果没有给出阈值则使用PlayerSettings 中定义的阈值,同时dDist 返回距离。下面具体描述一下实现过程:首先,我们知道demeer5()主要是围绕三句话展开的,即(1)如果球可踢,则用最大力量踢球;(2)如果球不可踢且我是队友中最快到球的队员,则去截球;(3)其他情况按战略点跑位。我们可以围绕这三句话来实现角球策略。即在角球模式下(1)如果球可踢,则传球给接应球员;(2)如果球不可踢且我是队友中最快到球的队员,则去发球;(3)其他情况下,如果我是离球次近的队员,那么我去接应。接着,有了这个基本思想后,我们开始编写代码。在demeer5() 中找到Else if ( WM->isBallKickable() ){ // if kickable 在里面加入我们的角球代码:If ( WM-> isCornerKickUs() ){ ACT->putCommandInQueue(kickTo(pointToKickTo(),SS->getBallSpeedMax()* 0.8 )); 18 } 这一部分代码是完成开球动作。函数pointToKickTo()是Player 类的成员函数,返回一个VecPosition 类型的参数,代表要将球踢向的坐标。下面给出一段参考代码:VecPosition Player::pointToKickTo(){ VecPosition pos,temp; double x,y; pos=WM->getBallPos(); x=pos.getX(); y=pos.getY(); temp.setX(-x/fabs(x)*5+x); temp.setY(-y/fabs(y)*12+y); return temp; } 再在demeer5()中找到else if( posAgent.getDistanceTo(WM->getStrategicPosition()) >1.5 + fabs( posAgent.getX() - posBall.getX() ) / 10.0) // if not near strategic pos 在里面加入如下代码:if ( WM-> isCornerKickUs() ) { ObjectT o; SoccerCommand sctemp; o = WM->getSecondClosestInSetTo(OBJECT_SET_TEAMMATES, OBJECT_BALL); if ( o = WM->getAgentObjectType() ){ sctemp = ACT->putCommandInQueue( moveToPos( pointToKickTo(), PS->getPlayWhenToTurnAngle() ); } ACT = putCommandInQueue( turnNeckToObject( OBJECT_BALL, sctemp )); } 这段代码是实现接应球员的跑位。这样,一个简单的角球策略就实现了。同学们可以编译运行看看效果。(3) 界外球(kick_in)当一方球员将球踢出边线时,比赛即进入界外球模式。比赛的规则要求基本同角球。简单的设计思路和实验内容与角球也差不多,在此不再赘述。要求同学们编写一段程序实现界外球策略,要求能够根据发球点的位置给出合适的接应球员的接应位置。可能用到的函数:bool WorldModel::isKickInUs() 返回是否是我方开界外球。if(WM->isKickInUs())//我方界外球 { if(WM->getAgentObjectType()==OBJECT_TEAMMATE_11) 19 { soc =leadingPass(OBJECT_TEAMMATE_9,2); //传球给9 号 } if(WM->getAgentObjectType()==OBJECT_TEAMMATE_10) { soc=leadingPass(OBJECT_OPPONENT_9,2); //传球给9 号 } if(WM->getAgentObjectType()==OBJECT_TEAMMATE_5) {} if(WM->getAgentObjectType()==OBJECT_TEAMMA TE_4) {} if(WM->getAgentObjectType()==OBJECT_TEAMMA TE_7) {} } (4) 定位球/任意球(free_kick) 当一方球员犯规或违例时,由对方开任意球。跟国际足联的规定略有不同的是,Robocup 的任意球没有直接任意球跟间接任意球之分。比赛的规则要求基本同界外球。(5) 球门球(goal_kick) 当对方进攻球员将球踢出底线或我方守门员截住对方射门的球时,由我方守门员开门球。注意,如果守门员截住的是己方后卫的回传球,那么会由对方球员在离截球点最近的禁区角点发任意球,因为这是违例行为。如果守门员在300 周期内不能将球开出,那么由对方球员在离开球点最近的禁区角点发任意球。在UV A_trilearn 的源代码中,守门员开球也是直接将球踢向对方球门。而开门球是一个比较复杂且非常重要的细节,许多强队,诸如清华、科大,都有不错的开门球策略。我们这次实验只完成一个简单的策略,即守门员沿某一直线开球,该直线是最近对方球员、守门员、次近对方球员三点所构成角的角平分线。
/
本文档为【机器人足球仿真实验报告】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
热门搜索

历史搜索

    清空历史搜索