RoboCup智能机器人足球教程(二)

2023-05-16

RoboCup智能机器人足球教程(二)

运行方式

RoboCup2D仿真平台通过一个服务端,若干客户端联系而成,同时通过监视器进行画面播放。当启动服务端后,客户端通过改写程序内部的client.cpp文件来实现球员逻辑,编译后即可与服务端进行连接,从而进行比赛。

因此我们要做的主要工作就是改写client.cpp,以实现球员逻辑。该文件位于Robocup/rcssserver-15.2.2/src/client.cpp,当改动完毕后,进入rcssserver-15.2.2文件夹,打开终端,执行

make

即可把客户端修改编译成功,从而进行比赛。

函数介绍

在client.cpp中,我们需要修改的,是以下几个函数,其他函数均不用修改。

main()

该函数为主函数,主要功能是接收参数和初始化client类,下面着重讲一些重要的代码片段,其他代码均不需要过多修改。

std::string server = "localhost";
int port = 6000;

这两条语句是设定服务器在本机上,端口号为6000,在测试阶段,可以不做修改,如果比赛中服务器不在本机上,那么就需要修改为相应的IP地址了。

for (int i = 0; i < argc; ++i) { // 进行id分配
    if (std::strcmp(argv[i], "-server") == 0) { 
        if (i + 1 < argc) {
            server = argv[i + 1]; 
            ++i;
        }
    } else if (std::strcmp(argv[i], "-port") == 0) {
        if (i + 1 < argc) {
            port = std::atoi(argv[i + 1]); // 端口号
            ++i;
        }
    }
    if (std::strcmp(argv[i], "-id") == 0) { // id
        if (i + 1 < argc) {
            iPlayerId = std::atoi(argv[i + 1]);
            ++i;
        }
    }
    if (std::strcmp(argv[i], "-sidel") == 0) { // 是左边的还是右边的
        iSide = 1;
    }
    if (std::strcmp(argv[i], "-sider") == 0) { 
        iSide = 2;
    }
}

这些代码是解析参数,在参数中获得队员的ID和所属队伍,也可以修改比较条件来创造自己的参数。

client = new Client(server, port);
client->run();

初始化客户端并执行。

run()

该函数是用来初始化球员位置,和开启消息循环,注意,一个客户端只能初始化一个球员,要想初始化11个球员,需要打开11个客户端。

if (iSide == 1) { // 初始化所有球员
    if (iPlayerId == 1) {sprintf(command, "(init team1 (goalie))");}// 第一个球员是守门员
    else {sprintf(command, "(init team1)");}
} else if (iSide == 2) {
    if (iPlayerId == 1) {sprintf(command, "(init team2 (goalie))");}
    else {sprintf(command, "(init team2)");}
} else {return;}
if (!sendCmd(command)) return;

if (iPlayerId == 1) {sprintf(command, "(move -45 0)");} // 球员的放置,守门员单独放到一个地方
else {sprintf(command, "(move -3 0)");} // 其他的都放到一个地方
if (!sendCmd(command)) return;

上面代码是根据ID来判断是否生成守门员或者其他球员(守门员单独用一个逻辑,其他球员用同一种逻辑。),并将球员放置在球场上合适位置。

sendCmd()函数的作用是把命令发送给服务器,从而实现球员的各种动作,这是RoboCup程序的运作方式,当球员要执行某种动作的时候,只需要将相应的字符串发送给服务器即可,例如奔跑的命令为(dash 100),踢球的命令为(kick 100),所有命令的解释在百度网盘的文件夹下,地址在这里

messageLoop();

本代码段为开启消息循环,开启消息循环后,将接收来自服务器和本地终端上的信息,通过解析这些信息,从而编写球员逻辑。

parseMsg()

最重要的函数,用来实现球员逻辑,通过函数传来的参数msg(发送过来的消息字符串)和len(字符串长度),从信息中截取有用信息,并做下一步动作。
发送来的最重要的信息有如下两种:

(sense_body 0 (view_mode high normal) (stamina 8000 1) (speed 0) (kick 0) (dash 0) (turn 0) (say 0))

该信息由服务端发送而来,大约每个时间周期发送一次(一个时间周期约几十毫秒),用于球员认知自身状态,该信息以sense_body开头,其后紧随的数字为比赛进行时间(为0表示还未开始比赛),其他信息意义如下:

  • stamina 球员体力值,8000为最大,执行动作后体力值会降低,降低到一定程度后球员变红,运动能力大幅下降,但经过休息后会回复。
  • speed 球员此刻的近似速度。
  • kick 球员总共踢了多少次球
  • dash 球员总共冲锋了多少次
  • turn 球员总共转身了多少次
  • say 球员总共说了多少次话

更多信息定义,请参照百度网盘文件夹中附带的ppt

(see 0 ((flag c) 3 0 0 0) ((flag r t) 65.4 -31) ((flag r b) 65.4 31) ((flag g r b) 55.7 7) ((goal r) 55.7 0) ((flag g r t) 55.7 -7) ((flag p r b) 43.8 27) ((flag p r c) 38.9 0) ((flag p r t) 43.8 -27) ((ball) 3 0 0 0) ((line r) 55.7 90))

该信息由服务端发送而来,大约每个时间周期发送一次(一个时间周期约几十毫秒),是球员的视野,该信息以see开始,其后紧随的数字仍然为为比赛进行时间,其后的信息是它所看到的球员,球(如果它能看见),和球场的标志,其后紧随的两个数字分别是极坐标下与自身的距离和角度(顺时针正方向),关于球场标志,可参照下图:

在这里插入图片描述

if (iPlayerId == 1) { // 守门员的代码
        if (std::strncmp(msg, "(see ", 5)) { 
            return;
        }
        double ball_dist = 0; // 球的方向
        double ball_dir = 0; // 球的角度
        char command[20]; // 命令缓冲
        char *pball; 
        pball = strstr(msg, "(ball)"); // ball是msg的一个子串,是则返回"ball"地址
        if (pball == 0) {
            sprintf(command, "(turn 60)"); // 转60度
            if (!sendCmd(command)) return; // 发送数据
            return;
        }

        if (std::sscanf(pball, "(ball) %lf %lf", &ball_dist, &ball_dir)!= 2) { // 没有辨别出球的方位和角度
            printf("get ball error\n"); // 获取球失败
            return;
        }

        if (ball_dist < 3) { // 如果与球的距离小于3
            sprintf(command, "(catch %lf)", ball_dir); //发送catch命令以捕获球
            if (!sendCmd(command)) return; // 永远的发送数据
            return;
        }
        if (ball_dir > 10 || ball_dir < -10) { // 如果与球的角度相差太大
            sprintf(command, "(turn %lf)", ball_dir); // 转向球的方向
            if (!sendCmd(command)) return;
            return;
        }
    } 

这些是守门员的所有逻辑,守门员(默认ID为1的球员是守门员)的逻辑为:如果球离自己比较近,就前去扑球,并朝对面踢出,代码注释比较详细,就不详细解释了。

RoboCup智能机器人足球教程(一)
RoboCup智能机器人足球教程(三)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RoboCup智能机器人足球教程(二) 的相关文章

随机推荐

  • 北京/西安内推 | 中国移动研究院NLP组招收自然语言处理算法实习生

    合适的工作难找 xff1f 最新的招聘信息也不知道 xff1f AI 求职为大家精选人工智能领域最新鲜的招聘信息 xff0c 助你先人一步投递 xff0c 快人一步入职 xff01 中国移动研究院 中国移动研究院 AI 中心是中国移动研究院
  • tcp 三次握手和四次挥手报文分析

    1 xff0c tcp 三次握手 报文抓取如下 xff1a 三段报文分析 xff1a 第一次 xff1a 26 gt 96报文交互 Seq num 61 567391014 ACK NUM 61 0 flags 61 SYN 第二次 xff
  • bootp引导程序协议

    bootp又称为引导程序协议 我们来简单了解一下这个协议以及他的用法 1 xff0c BOOTP 请求和应答均被封装在 U D P 数据报中 xff1b 2 xff0c B O O T P 使用 U D P xff0c 且通常需与 T F
  • http请求学习

    GET xff1a 向Web服务器请求一个文件 POST xff1a 向Web服务器发送数据让Web服务器进行处理 PUT xff1a 向Web服务器发送数据并存储在Web服务器内部 HEAD xff1a 检查一个对象是否存在 DELETE
  • linux c语言全面学习json解析函数

    1 json结构的定义 typedef struct cJSON cJSON结构体 struct cJSON next prev 遍历数组或对象链的前向或后向链表指针 struct cJSON child 数组或对象的孩子节点 int ty
  • matlab的图片滤波处理

    椒盐噪声 高斯噪声 MATLAB自带函数 均值滤波 中值滤波 自编模版 读取图片并转换为灰度图片 I 61 imread 39 1 jpg 39 imshow I I1 61 rgb2gray I imshow I1 椒盐噪声 I2 61
  • Linux 动态库的编译和执行

    静态库生成及测试 编码myccso脚本 gcc c Wall I inc src myadd c o myadd o ar rcs libmyadd a myadd o rm o mv libmyadd a lib gcc Wall g I
  • matlab中函数的定义和使用

    在matlab的选择框中的的新建中选择新建函数 xff0c 一般是以 m的文本文件 xff0c 新建后我们可以在里面写入我们的实现函数 xff0c 现在我们给出两个实例看一下 xff0c 分别是简单的求和和Fibonacci sequenc
  • matlab简单绘图plot,subplot

    a1 二维绘图plot的实现 subplot n m x 建立一个m n的绘图区域 xff0c 然后分别在其x 61 1 xff0c 2 xff0c 3 xff0c 4 区域绘制图像 function 61 plot1 x 61 0 0 3
  • python 函数的定义和应用

    1 xff0c 函数定义和使用 xff1a def substract sub a sub b sub res 61 sub a sub b return sub res sub test 61 substract 10 20 print
  • Linux shell中的-d,-f,-e,-n的作用

    1 xff0c d gt dirtionnary 判断目录是否存在 例 xff1a d tmp 返回为真便是 tmp是文件夹目录 2 xff0c e gt exist 判断是否存在 例 xff1a e filename 返回为真表示file
  • 「第四范式」2023届-秋季校园招聘正式启动!

  • Linux下用nginx和naxsi搭建web防火墙

    Linux下用nginx和naxsi搭建web防火墙 Naxsi Naxsi是一个开源 xff0c 高性能 xff0c 地位会规则 xff0c nginx的web应用程序防火墙模块 xff0c 著名的web服务器和反向代理 xff0c 它的
  • 【语义分割】类别不平衡损失函数合集

    在语义分割领域 xff0c 我们会常常遇到类别不平衡的问题 比如要分割的目标 xff08 前景 xff09 可能只占图像的一小部分 xff0c 因此负样本的比重很大 xff0c 导致网络倾向于将所有样本判断为负样本 本文介绍了在数据不平衡时
  • 小张学linux内核:十四. elf文件的加载和进程切换寄存器的保存

    重点关注虚拟内存的切换 xff0c pgd xff0c mm struct start code xff1b 理清楚这三个概念 pgd不是在这里设置的遵循COW xff0c 是在写时缺页中断填充的 start code只是一个段开始的标记
  • linux软中断和系统调用深入研究

    arm软中断模式 arm7种模式 有中断模式 xff0c 但是并没有软中断模式 那么arm的软中断是什么呢 xff1f arm的软中断是arm从用户模式切换到特权模式 xff0c 也就是linux中从用户态切换到内核态的过程 swi命令触发
  • 进程proc文件介绍

    进程proc文件 proc pid 下是每个进程的proc信息 xff0c proc self比较特殊 xff0c 哪个进程打开 xff0c 对应链接到哪个进程 1 xff09 内存相关 status xff1a 进程使用虚拟内存和物理内存
  • Win10系统下安装CAA二次开发程序,VS界面上不出现CAA菜单栏或菜单栏为灰色的

    问题描述 xff1a Win10系统下安装了CATIA CAA V5R19和V4R24两个版本 xff0c 其中V5R19版本安装完成后VS2005中没有出现CAA菜单栏 xff0c V5R24安装完成后VS2008中出现部分集成菜单且为灰
  • 基于Stm32的4G模块实现内网透传通信(代码后附)

    基于Stm32的4G模块实现内网透传通信 一 内网透传即内网映射 xff0c 内网IP端口映射外网连接访问过程的实现 内网透传通信实现过程又有以下几种区别 xff1a 1 xff09 路由器映射 适合自己本地路由有公网IP网络环境 xff0
  • RoboCup智能机器人足球教程(二)

    RoboCup智能机器人足球教程 xff08 二 xff09 运行方式 RoboCup2D仿真平台通过一个服务端 xff0c 若干客户端联系而成 xff0c 同时通过监视器进行画面播放 当启动服务端后 xff0c 客户端通过改写程序内部的c