仿真机器人球队程序框架解读_第1页
仿真机器人球队程序框架解读_第2页
仿真机器人球队程序框架解读_第3页
仿真机器人球队程序框架解读_第4页
仿真机器人球队程序框架解读_第5页
已阅读5页,还剩81页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第4章仿真机器人球队程序框架基本原理介绍4.1消息的解析和发送模块4.2几何计算模块4.3辅助模块4.4WorldModel模块4.5基本动作模块4.6决策模块4.7日志模块4.8启动球员上场模块基本原理基本原理基本原理负责消息接受和动作发送的模块:Connetion、ActHandler和SenseHandler类辅助模块:Geometry类、Parse、GenericValues、ServerSettings、SoccerTypes、PlayerSettings、Formations…….等类世界模型模块:WorldModel类基本动作模块:BasicPlayer类决策模块:Player类日志模块:Logger类启动球员上场模块:main.C4.1消息的解析和发送模块Server与Client之间是通过基于UDP/IP协议进行信息(普通字符串)传输的。Connection.h定义了——_socket和Connection类负责最底层的信息传递,它只负责字符串的传输。SenseHandler.h定义了一个类SenseHandler,它是基于Connection基础上进行感知信息的处理的,然后把处理好的信息交给WorldModel.ActHandler.h定义了一个类ActHandler,它是基于Connection基础上进行特定动作的发送处理的,要把特定动作(包括原子动作和高级动作)处理成Server能够理解的字符序列。4.1.1Connection.h和Connection.CConnection.h文件包含有_socket结构(被重定义成Socket类型)和Connection类;它是球员Cient与Server进行通讯的基础。socket结构(套接字)是一个文件描述符与服务器地址的结合,包含以下成员:intsocketfd//套接字文件描述符structsockaddr_inserv_addr

//服务器套接字信息注意:sockaddr结构在netdb.h和arpa/inet.h中说明,因此,Connnection.h文件需要包含这两个文件。Connection类通过定义服务器名和端口号等属性与服务器建立Socket连接。连接建立好以后就可以通过连接接收和发送消息;它是球员Client与Server通讯的基础。Connection类成员:Socketm_soc //服务器通信协议,一个Socket类型的对象成员intm_iMaxMsgSize//最大信息长度成员函数:Connection()//缺省构造函数,只是设置最大信息长度Connection(constchar*hostname,intport,intiSize)

//构造函数。与指定服务器服务器建立连接;其中参数:hostname可以是字符串也可以是Ip地址,port表示端口号,isize表示可以接受和发送信息的最大长度~Connection()//析构函数。断开连接boolconnect(constchar*host,intport)

//注意,这不是构造函数,它主要是建立与指定服务器名和端口号的服务器建立连接;参数说明同上,函数根据连接是否成功返回1和0voiddisconnect(void)//断开当前socket连接boolisConnected(void)const//判断是否已连接。如果已经建立连接返回1,否则返回0intmessage_loop(FILE*fpin,FILE*fpout)//该方法保持循环状态等待输入。如果从fpin接到输入,则将该输入通过连接发送到服务器;如果从服务器接到消息,则将该消息送到fpout。参数说明:fpin和fpout分别是文件读指针和文件写指针。当读写失败时返回0intreceiveMessage(char*msg,intmaxsize)//该方法从连接读入一个消息,如果没有消息则阻塞直到接到消息。参数说明:msg表示从连接中读入信息的指针,maxsize表示最长可以读的字节数。当读入出错时返回-1,读入0个字节还在等到信息时返回0,成功读入信息返回1boolsendMessage(constchar*msg)//该方法通过连接向服务器发送消息。参数说明:msg指针指向内容就是要发送的信息。发送成功返回1voidshow(ostreamos)//该方法向指定的输出流打印是否处于连接状态。os为输出流4.1.2SenseHandler.h和SenseHandler.CSenseHandler.h主要包含一个全局函数void*sense_callback(void*v)、一个全局变量LoggerLog以及SenseHandler类。它负责处理从Server端感知到的信息。其中全局函数void*sense_callback(void*v)是用来启动Sense线程;负责感知从Server端感知信息的;然后调用SenseHandler类里面的handleMessagesFromServer函数进行信息处理的。LoggerLog是用来记录日志信息的。4.1.2SenseHandler.h和SenseHandler.CSenseHandler类通过创建Connection的一个实例,连接并接收服务器发来的消息。它包含很多方法,用于解析接到的消息并将结果送到相应的世界模型中。当该类实例化后,一个特殊的线程就会调用全局函数函数sense_callback;在该函数中调用handleMessagesFromServer(),而handleMessagesFromServer()函数将一直保持循环状态;通过这种方式,所有的消息将以这种方式被接收然后解析。SenseHandler类WorldModel*WM

//世界模型实例ServerSettings*SS

//服务器相关参数信息PlayerSettings*PS

//球员相关参数信息Connection*connection//与服务器的连接实例intiTimeSignal

//感知动作之前等待时间intiTriCounter

//表示视觉信息何时到来intm_iSeeCounter

//用来表示一个周期内see消息的次数intiSimStep //服务器周期的长度itimervalitv //发送动作的计时器SenseHandler类SenseHandler(Connection*c,WorldModel*wm,ServerSettings*ss,PlayerSettings*ps)//构造函数。需要一个对连接的引用和一个对世界模型的引用voidhandleMessagesFromServer()

//该类的最主要程序,保持循环,接收、解析收到的消息voidsetTimeSignal()//该方法设置时间信号。这是将下一个动作发送到服务器前所要等待的时间。当一个sense收到一个感觉信息后该方法被调用boolanalyzeMessage(char*strMsg)

//根据给定消息的类型调用相应的方法,分析给定的消息boolanalyzeSeeGlobalMessage(char*strMsg)//该方法分析一个视觉消息。其所包含的不同对象的信息将被送往世界模型SenseHandler类boolanalyzeSeeMessage(char*strMsg)

//该方法分析一个视觉信息。它从服务器得到时间,并试着与服务器保持同步。然后将消息存储在世界模型中,当调用update的时候更新boolanalyzeSenseMessage(char*strMsg)//该方法分析一个感觉消息。其所包含的不同对象的信息将被送往世界模型boolanalyzeInitMessage(char*strMsg)

//该方法分析一个初始化消息。其所包含的初始化信息将被送往世界模型boolanalyzeHearMessage(char*strMsg)

//该方法分析一个听觉消息。当该消息是发自裁判的,则根据其所包含的信息更新比赛模式,调整比分差;如果该消息是发自其他球员的,则调用analyzePlayerMessage进行处理SenseHandler类boolanalyzePlayerMessage(char*strMsg)

//该方法分析一个球员间通信消息。首先,该方法检查该信息是否是来自队友,对方球员的消息将被忽略,然后将该消息解析,所获得的信息存储在世界模型中,当更新世界模型时进行处理boolanalyzeChangePlayerTypeMessage(char*strMsg)

//该方法分析一个改变球员类型消息。它检查是否当前agent要改变类型,如果是根据该类型调整ServerSettings

boolanalyzeServerParamMessage(char*strMsg)

//该方法分析server_param消息。该消息包含了所有服务器参数。所有ServerSettings中的设置将根据给出的值而改变。这将使从server.conf读出的配置值作废SenseHandler类boolanalyzeCheckBall(char*strMsg)

//该方法分析check_ball消息。该消息只有coach能够借收。它设置世界模型中的球的状态boolanalyzePlayerTypeMessage(char*strMsg)//该方法分析一个球员类型消息。该消息包含一个异构球员的类型值。这些值将被解析出并提供给世界模型中方法processNewHeteroPlayer。boolanalyzePlayerParamMessage(char*strMsg)

//该方法分析player_param消息。它包含了异构球员各属性值的取值范围。boolreadServerParam(char*strParam,char*strMsg)//该方法读出由字符串strParam所包含的服务器参数ServerSettings中的各属性将根据这些参数设置。文件包含关系4.1.3ActHandler.h和ActHandler.CActHandler.h主要包含一个全局函数voidsigalarmHandler(inti)、一个全局变量LoggerLog以及ActHandler类。它负责向Server发送信息。其中,全局函数voidsigalarmHandler(inti)在SIGALARM信号到达时被执行;该信号到达时间在SenseHandler中定义。当信号到达时,存储在ActHandler命令队列中的命令被发送到服务器。全局变量LoggerLog的作用同上。4.1.3ActHandler.h和ActHandler.CActHandler类主要负责向服务器发送动作;它包含一个命令队列。当SIGALARM信号到达时,队列中的动作将被转化成字符串并发送到服务器;发出的动作同时也发送到世界模型,世界模型可以根据相应动作的执行而更新自己的内部状态。某些动作可以在一个时间周期内发送多个,而某些命令每个周期只能发送一条,因此内部设置了两个任务队列。一个队列只有一个元素,即主动作;另一个队列包含了附加动作。当一个新动作进入一个已经包含其它的队列,则队列中的老动作被新动作更新。此外,也可以直接将命令发送到服务器。这些方法可以用于将初始化或move命令送到服务器,同时可以肯定这些命令是最终的,即不需要再根据服务器发来的信息更新。4.1.3ActHandler.h和ActHandler.CWorldModel*WM

//世界模型实例ServerSettings*SS

//服务器相关参数信息Connection*connection//与服务器的连接实例SoccerCommandm_queueOneCycleCommand //单命令队列SoccerCommandm_queueMultipleCommands[MAX_COMMANDS]//多命令队列intm_iMultipleCommands

//多命令队列里的命令数4.1.3ActHandler.h和ActHandler.CActHandler(Connection*c,WorldModel*wm,ServerSettings*ss)//构造函数。所有的变量初始化boolputCommandInQueue(SoccerCommandcommand)//该方法将command放入命令队列,最后放入队列的命令,将在sendCommands执行的时候被发送到服务器。这通常在收到SenseHandler发来的信号后执行voidemptyQueue()//清空任务队列boolisQueueEmpty()

//判断任务队列是否为空boolsendCommands()//该方法将任务队列中的所有动作转化成字符串,并通过Connection发送到服务器。当服务器没有执行上个周期的动作时,为了避免冲突当前命令并不发送。这时返回false4.1.3ActHandler.h和ActHandler.CboolsendCommand(SoccerCommandsoc)

//该方法直接发送一个单独的命令到服务器boolsendMessage(char*str)

//该方法将一个字符串直接发送到服务器。为了保证该信息到达,该信息发送后将等待一个周期boolsendCommandDirect(SoccerCommandsoc)

//该方法将一个命令直接发到服务器boolsendMessageDirect(char*str)//该方法将一个字符串直接发送到服务器4.2几何计算模块该模块主要是为实现一些实现对球场位置进行识别、分析和处理而涉及到的一些辅助类,包括VecPosition,Geometry,Line,Circle和Rectangle等类。全部在Geometry.h中定义,在Geometry.C中实现。还包括一些常量的定义如:#defineEPSILON0.0001//浮点型数据相等误差。对double类型进行了AngRad(弧度)和AngDeg(角度)等类型的重定义。申明了一个枚举类型enumCoordSystemT{CARTESIAN,POLAR}表示计算时需要采用的坐标系类型。定义了一些全局函数:doublemax(doubled1,doubled2)doublemin(doubled1,doubled2)intsign(doubled1) //符号函数,正数返回1,零和负数返回-1AngDegRad2Deg(AngRadx) //弧度转角度AngRadDeg2Rad(AngDegx) //角度转弧度doublecosDeg(AngDegx)doublesinDeg(AngDegx)doubletanDeg(AngDegx)AngDegatanDeg(doublex)doubleatan2Deg(doublex,doubley)//返回y/x的弧正切的住值,同时由x,y的符号决定象限AngDegacosDeg(doublex)

AngDegasinDeg(doublex)boolisAngInInterval(AngDegang,AngDegangMin,AngDegangMax)//角度是否在给定范围内AngDeggetBisectorTwoAngles(AngDegangMin,AngDegangMax)//返回角平分线VecPosition类用来表示位置坐标的以及在此基础上面的一些运算。Circle类表示一个圆,它包含一个VecPosition类的对象成员表示圆心,另外一个成员表示半径。Line类表示直线类,直线可以表示成ay+bx+c=0.因此可以使用系数a,b,c表示一条直线。Rectangle类用来表示一个矩形,一个矩形主要是由矩形的左上角和右下角的两点来确定。

Geometry类设计了一些如几何相关的静态方法,如:仿真表示中球员和球的速度衰减都遵循等比数列的,而Geometry类就是涉及到这方面计算的。xy(0,0)(52.5,0)(0,34)4.3一些辅助模块负责对字符串进行解析的模块-Parse.h对特定类型数据进行任意形式读写(设置)的模块-GenericValues.hServer相关参数读写(设置)和异构球员参数设置的模块-ServerSettings.h球员进行动作决策时需要的一些重要变量临界值的设置模块-PlayerSettings.h实际足球相关信息模块-SoccerTypes.h阵型模块-Formations.h球场对象模块-Object.h4.3.1Parse.h和Parse.CParse.h只包含一个类,那就是Parse类,它主要是用来负责对字符串进行解析。如:给定字符串1223.456ffffg,解析出来的第一个整数就是1223,一个实数就是1223.456等。staticdoubleparseFirstDouble(char**strMsg);//解析字符串中第一个Double类型数据,执行完该函数以后strMsg发生改变staticintparseFirstInt(char**strMsg);//解析字符串中第一个int类型数据,执行完该函数以后strMsg发生改变staticchargotoFirstSpaceOrClosingBracket(char**strMsg);//到达第一个空格或),执行完该函数以后strMsg发生改变staticintgotoFirstOccurenceOf(charc,char**strMsg);//返回字符c在strMsg中第一次出现的位置。执行完该函数以后,strMsg本身改变了staticchargotoFirstNonSpace(char**strMsg);//返回第一个非空格字符4.3.2GenericValues.h和GenericValues.C对特定类型数据进行任意形式读写(设置)的模块,包括GenericValueT类和GenericValues类和一个枚举类型GenericValueKind枚举类型GenericValueKind{GENERIC_VALUE_DOUBLE=0,GENERIC_VALUE_STRING=1,GENERIC_VALUE_BOOLEAN=2,GENERIC_VALUE_INTEGER=3,};GenericValueT类GenericValueT类提供了一种通用的数据类型,用变量名、变量地址和变量类型间接表示一个变量,可以表示double,char*,int,bool这四种类型的变量。constchar*m_strName//变量名void*m_vAddress//变量地址GenericValueKindm_type//变量类型GenericValues类GenericValues类主要包含一系列的GenericValueT类型的成员;用m_strClassName表示各种不同类型的变量。该类是一个抽象类,因此它不能直接创对象;后面的ServerSettings和PlayerSettings类都是它的派生类,再派生类中通过addSetting可以设置具体类型;GenericValues主要用来读入配置文件。char*m_strClassName

//该组通用变量的名称GenericValueT**m_values//指向保存所有通用变量数组的指针intm_iValuesTotal

//当前所保存的通用变量的数目intm_iMaxGenericValues//该实例能保存的最大的通用变量数目4.3.3ServerSettings.h和ServerSettings.CServerSettings.h文件包含2个类,ServerSettings类和HeteroPlayerSettings类,ServerSettings类是GernericValues类的派生类,包含了Server配置文件(serv.erconf)中的所有参数,和对这些参数赋值,取值的方法。HeteroPlayer类用来表示所有异构球员信息的类。包含所有关于定义异构球员的参数。每个球员的类型参数将在服务器启动时开始随机初始化,一旦确定比赛过程中保持不变。4.3.4PlayerSettings.h和PlayerSettings.CPlayerSettings.h文件包含一个类,那就是PlayerSettings类,它也是GenericValues类的派生类。PlayerSettings类里面主要包含球员进行动作决策时需要的一些重要变量临界值的设置。如,在实际比赛当中,由于受到视觉的限制,可能一些队员一段时间都没有被观察到,这时需要判断世界模型中存储的该队员以前的信息是否有效和可用,就可以设置一个球员信息可信度这样一个变量,根据观察到的时间距离现在时间的长短,设置一个临界值,超过该临界值的信息将得不到利用,而没有超过该临界值的信息则认为是有效的。4.3.5SoccerTypes.h和SoccerTypes.C足球本身相关信息一些常量的定义一些枚举类型的定义SoccerCommand类SoccerTypes类Time类Time类Time类该类包含了对服务器时间的表示形式。它由一个序偶(t,s)组成。t表示当前服务器的周期数,s表示服务器时钟停止的周期数。t的值等于从服务器收的的最后一个信息的时间戳。服务器运行的时候s的值恒为0,只有当死球的时候s的值才会有所变化。SoccerCommand类SoccerCommand类以字符串的形式表示命令,其格式自由与server的格式不同,在将其传给server再将相应的命令转化成标准格式。该类完成的工作如下:根据传入的参数,建立一个容易理解,且可以灵活改变的命令实例,当对命令处理完后,再将命令转化成server可以理解的命令字符串。SoccerTypes类SoccerTypes类包含了很多对SoccerTypes.h中定义的枚举类型进行的操作,和这些枚举类型与SoccorServer所规定的字符串型之间的转化。它的所有成员函数都是公有静态成员函数。4.3.6Formations.h和Formations.C该文件定义了与场上阵型相关的一些信息。PlayerTypeInfo类-对SoccerTypes.h中定义的每一种球员类型PlayerT的信息进行进一步扩充FormationTypeInfo类-SoccerTypes.h中定义的每一种阵型类型FormationT的信息进行进一步扩充Formations类-是一个阵型信息容器。包含了所有不同的阵型类型信息,还包含了球员当前的阵型以及球员在该阵型中的角色这2个属性。同过这2个属性就很容易确定该队员在阵型中的位置。4.3.7Object.h和Object.C包含所有比赛中所有对象可用的信息。与agent有关的信息在AgentObject中声明。类中提供了对自由属性的访问函数ObjectTobjectType

//对象类型TimetimeLastSeen

//上次视觉信息接收时间VecPositionposGlobal

//全局位置TimetimeGlobalPosition //更新全局位置的服务器时间VecPositionposRelative //相对agent的位置TimetimeRelativePosition

//更新相对位置的服务器时间VecPositionposGlobalLastSee//上次接收到视觉信息时的全局位置TimetimeGlobalPosDerivedFromSee//从上次视觉信息得出的位置的时间Object类FixedObject类即固定对象类,主要是是用来记录了不能移动的对象的信息。如标志,球门,线等。DynamicObject类动态对象类,该类主要是用来记录移动对象的信息。VecPositionvecGlobalVelocity//绝对速度。注意这是一个矢量TimetimeGlobalVelocity//记录绝对速度的时间doubledRelativeDistanceChange//相对距离的改变doubledRelativeAngleChange//相对角度的改变TimetimeChangeInformation//改变信息的时间BallObject类含球的所有信息,对DynamicObject类并没有增加新的成员PlayerObject类即球员类,对DynamicObject类增加了一些成员和方法。

boolisKnownPlayer//该球员号码的可信度是否足够高。ObjectTobjRangeMin//对象类型范围的最小值ObjectTobjRangeMax//对象范围的最大值boolisGoalie//是否是守门员AngDegangGlobalBodyAngle//绝对身体角度AngDegangGlobalNeckAngle//绝对脖子角度TimetimeGlobalAngles//绝对角度改变时间AgentObject类它在类PlayerObject上面扩充了体力、视觉等相关属性和方法。ViewAngleTviewAngle //视角宽度ViewQualityTviewQuality//视觉质量Staminastamina //体力VecPositionvelSpeedRelToNeck

//相对于脖子的速度AngDegangBodyAngleRelToNeck//相对于脖子的身体角度VecPositionposPositionDifference//位置差Stamina类

体力类;该类包含SoccerServer所定义的与体力相关的参数。doublem_dStamina//球员体力doublem_dEffort//体力效用doublem_dRecovery//体力恢复4.4WorldModel模块WorldModel模块是球员进行决策的基础,它描述了球场所有对象(如球员、球、标志、线等)的信息(包括位置信息和速度信息以及其他一些信息,如身体朝向等等)以及比赛信息等。它的属性主要分为以下4类:Environmentalinformation环境信息包含:服务器参数,异构球员取值范围,每一种异构球员的参数Matchinformation比赛信息包含:Time,PlayerNumber,Side,TeamName,PlayMode,GoalDiff(比分差)Objectinformation对象信息包含各类对象且有继承关系Actioninformation动作信息包含:每种动作执行的次数,动作队列,已经执行的动作4.4WorldModel模块在WorldModel.h中定义了一个类WorldModel,就是用来表示这些信息的,我们也把它称为世界模型。其所包含的方法可分为四类:Retrievalmethods 从球员的世界模型中获得对象的信息Updatemethods 从来自server的感觉信息更新球员的世界模型Predictionmethods 根据先前的感觉信息预测世界的将来的状态High-Levelmethods 从基本的世界模型信息得出高层的结论4.4WorldModel模块这四种不同实现的方法分布在四个不同的.C文件中,他们分别是:WorldModel.CWorldModelUpdate.CWorldModelPredict.CWorldModelHighLevel所有具体WorldModel成员和成员函数见讲义。Retrievalmethods

voidsetTimeLastCatch(Timetime)//设置上次扑球的时间。该信息是通过SenseHandler当裁判发送该信息时得到的。intgetTimeSinceLastCatch()//返回自从上次扑球以后经过的周期数。boolsetTimeLastRefereeMessage(Timetime)//设置上次接受裁判信息的时间。TimegetTimeLastRefereeMessage()//返回上次接受裁判信息的时间。TimegetCurrentTime()//返回当前时间。如果球员调用,返回上次感觉的时间;如果是教练调用,返回上次see_globlemessage时间。..................UpdatemethodsboolprocessNewAgentInfo(ViewQualityTvq,ViewAngleTva,doubledStamina,doubledEffort,doubledSpeed,AngDegangSpeed,AngDegangHeadAngle)//当接收到关于当前agent的新的视觉信息的时候,该方法被调用,以更新世界模型中存储的AgentObject类voidprocessNewObjectInfo(ObjectTo,Timetime,doubledDist,intiDir,doubledDistChange,doubledDirChange,AngDegangRelBodyAng,AngDegangRelNeckAng,boolisGoalie,ObjectTobjMin,ObjectTobjMax)//当接收到关于当前对象o的新的视觉信息的时候,该方法被调用,以更新世界模型中存储的有第一个参数指定的Object类。如果某些参数并没有从视觉信息中获得,将传入‘UnknownDoubleValue’值。注意,对象只有当相应得信息作为参数传入的时候才更新。为了确保关于该对象的所有全局信息的同步,updateAll()方法将在所有的对象的信息更新完了后被调用……………PredictionmethodsBoolpredictStateAfterCommand(SoccerCommandcom,VecPosition*pos,VecPosition*vel,AngDeg*angGlobalBody,AngDeg*angGlobalNeck,Stamina*sta=NULL)//该方法预测队员在给定的状态下执行完命令com后的新的状态。使用参数作为输入输出变量VecPositionpredictPosAfterNrCycles(ObjectTo,intiCycles,intiDashPower=100,VecPosition*vel=NULL)//该方法预测对象o经过iCycle周期后的位置。如果对象为球,则只考虑球速的衰减。如果对象是球员,则假设球员每周期使用iDashPower进行dash…………..High-LevelmethodsintgetNrInSetInCone(ObjectSetTobjectSet,doubledWidth,VecPositionstart,VecPositionend)//该方法返回,在指定的圆锥中,包含在对象集objectSet中的可视对象个数。只有当对象的可信度高与在PlayerSettings中定义的阈值才被考虑。ObjectTgetClosestInSetTo(ObjectSetTobjectSet,Linel,VecPositionpos1,VecPositionpos2,double*dDistToLine=NULL,double*dDistPos1ToP=NULL)//返回在对象集合objectSet中距离直线l最近的对象。只有当对象的可信度高与给定的阈值才被考虑,如果没有给出阈值则使用在PlayerSettings中定义的阈值。同时dDist返回距离。………….4.5基本动作模块ClassBasicPlayer类该类主要作用:该类定义球员Agent使用的skill。如何选择时机执行这些skill在该类里并没有给出,而在Player类(决策类)里给出,WorldModel被用于决定这些skill使用的方式。该类主要内容:Skill和一些根动作相关的有用方法Skill类别:LOW-LEVELSKILLSINTERMEDIATESKILLSHIGH-LEVELSKILLS4.5基本动作模块LOW-LEVELSKILLS(低级动作)SoccerCommandalignNeckWithBody();SoccerCommandturnBodyToPoint(VecPositionpos,intiPos=1);SoccerCommandturnBackToPoint(VecPositionpos,intiPos=1);SoccerCommandturnNeckToPoint(VecPositionpos,SoccerCommandcom);SoccerCommandsearchBall();SoccerCommanddashToPoint(VecPositionpos);SoccerCommandfreezeBall();SoccerCommandkickBallCloseToBody(AngDegang);SoccerCommandaccelerateBallToVelocity(VecPositionvel);SoccerCommandcatchBall();SoccerCommandcommunicate(char*str);SoccerCommandteleportToPos(VecPositionpos);4.5基本动作模块INTERMEDIATESKILLS(中间动作)SoccerCommandturnBodyToObject(ObjectTo);SoccerCommandturnNeckToObject(ObjectTo,SoccerCommandcom);SoccerCommandmoveToPos(VecPositionposTo,DAngegangWhenToTurn,doubledDistDashBack=0.0,boolbMoveBack=false);SoccerCommandinterceptClose();SoccerCommandinterceptCloseGoalie();SoccerCommandkickTo(VecPositionposTarget,doubledEndSpeed);SoccerCommandturnWithBallTo(AngDegang,AngDegangKickThr,doubledFreezeThr);SoccerCommandmoveToPosAlongLine(VecPositionpos,AngDegang,doubledDistThr,intiSign,AngDegangThr,AngDegangCorr);4.5基本动作模块HIGH-LEVELSKILLS(高级动作)SoccerCommandintercept(boolisGoalie);SoccerCommanddribble(AngDegang,DribbleTd);SoccerCommanddirectPass(VecPositionpos,PassTpassType);SoccerCommandleadingPass(ObjectTo,doubledDist);SoccerCommandthroughPass(ObjectTo,VecPositionposEnd,AngDeg*angMax=NULL);SoccerCommandoutplayOpponent(ObjectTo,VecPositionpos,VecPosition*posTo=NULL);SoccerCommandclearBall(ClearBallTtype,SideTs=SIDE_ILLEGAL,AngDeg*angMax=NULL);SoccerCommandmark(ObjectTo,doubledDist,MarkTmark);SoccerCommanddefendGoalLine(doubledDist);SoccerCommandinterceptScoringAttempt();4.5基本动作模块一些有用的方法:VecPositiongetThroughPassShootingPoint(ObjectTobjTeam,VecPositionposEnd,AngDeg*angMax);VecPositiongetInterceptionPointBall(int*iCyclesBall,boolisGoalie);VecPositiongetShootPositionOnLine(VecPositionp1,VecPositionp2,AngDeg*angLargest=NULL);doublegetEndSpeedForPass(ObjectTo,VecPositionposPass);VecPositiongetMarkingPosition(ObjectTo,doubledDist,MarkTmark);4.5基本动作模块实现举例:实现把身体转到特定点SoccerCommandBasicPlayer::turnBodyToPoint(VecPositionpos,intiCycles=1){VecPositionposGlobal=WM->predictAgentPos(iCycles,0);AngDegangTurn=(pos-posGlobal).getDirection();angTurn-=WM->getAgentGlobalBodyAngle();angTurn=VecPosition::normalizeAngle(angTurn);angTurn=WM->getAngleForTurn(angTurn,WM->getAgentSpeed());returnSoccerCommand(CMD_TURN,angTurn);}这个例子基本上是最简单的基本动作的实现了,其他动作的实现我们在教材上都有说明,在实验课的时候大家可以对这些动作做一些改变看一下效果的变化。4.6球员决策模块球员决策类-ClassPlayer,该类是BasicPlayer类的派生类,负责球场上面球员的决策。主要成员函数voidmainLoop();voiddeMeer5();voiddeMeer5_goalie(

);voidgoalieMainLoop();voiddefenderMainLoop();voidmidfielderMainLoop();voidattackerMainLoop();DeMeer5函数见4.8节4.7日志模块日志模块实际上也是一个辅助某块,但是本文把它放到了最后,主要原因就是因为每一个日志模块基本上都需要做日志记录;它贯穿了基本上所有模块。如,在感知信息的时候,需要做日志,在做决策时,需要做日志,发送动作时候还是需要做日志;这些日志信息可以为我们日后分析比赛的进程提供大大帮助;每当对球员在比赛时的决策比较困惑,可以据此分析得出到底是哪个部分出的问题。日志模块主要在Logger.h和Logger.C中定义和实现的。Logger.h里面包含有2个类,它们分别是Logger类和Timing类。其中Timing拥有一个计数器;而Logger类则负责些日志表头和具体的日志信息。Timing类private:timevaltime1public:voidprintTimeDiffWithText(ostream&os,char*str,intiFactor=1000)doublegetElapsedTime()voidrestartTime()staticdoublegetTimeDifference(structtimevalt1,structtimevalt2)Logger类private:Timingm_timingcharm_buf[MAX_LOG_LINE]set<int>m_setLogLevelscharm_strHeader[MAX_HEADER]ostream*m_ospubic:Logger(ostream&os=cout,intiMinLogLevel=0,intiMaxLogLevel=0)boollog(intiLevel,stringstr)boollog(inti,char*str,...)boollogWithTime(intiLevel,char*str,...)voidrestartTimer()TiminggetTiming()boolisInLogLevel(intiLevel)booladdLogLevel(intiLevel)booladdLogRange(intiMin,intiMax)char*getHeader()boolsetHeader(char*str)boolsetHeader(inti1,inti2)boolsetOutputStream(ostream&os)ostream&getOutputStream()voidshowLogLevels(ostream&os)4.8启动球员上场比赛模块创建与球员类密切相关的一些事例对象如:

Formationsfs(strFormations,FT_433_OFFENSIVE,iNr-1);WorldModelwm(&ss,&cs,&fs);Connectionc(strHost,iPort,MAX_MSG);ActHandlera(&c,&wm,&ss);SenseHandlers(&c,&wm,&ss,&cs);

然后创建一个球员对象:Playerbp(&a,&wm,&ss,&cs,&fs,strTeamName,dVersion,iReconnect);球员对象创建完毕,创建一个监听线程负责对Server端的信息进行监听。pthread_create(&sense,NULL,sense_callback,&s);一旦有信息来了则调用全局sense_callback函数进行信息处理。在实际比赛进程中,一直调用Player类的mainLoop方法;bp.mainLoop();假设:球员的决策思路是这样的:如果球可以被我踢,我则把球踢到球门中央;否则,我是否离球最近(或能否最快获得控球权),是的话,我就跑向球去阻截球,以获得控

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论