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

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

实现守门员代码

守门员逻辑实现比较容易,但是最好开始的时候画好流程图,理顺逻辑,守门员一直盯着球,当球距离守门员够近的时候,守门员前去扑球,扑到球后朝对面射出,逻辑图为:
在这里插入图片描述
实现逻辑的办法就是定义状态变量,用if控制,在这里,我们定义如下几个重要的状态变量:
isCatchBall: 球是否在脚下

isMove: 是否进行了瞬移,守门员扑到球后是可以进行瞬移的,我们要利用好。

主要架构的伪代码为:

if isCatchBall == true
    search goal
    kick
else
    if ball_distance < 1
        catch ball
    else 
        look at ball

下面是完全的代码:

if(id == 1){
    if (std::strncmp(msg, "(see ", 5)==0){
        if(isCatchBall == 0){
            double ball_distance = 0; // 球的方向
            double ball_direction = 0; // 球的角度
            char *p; 
            p = strstr(msg, "(ball)"); 
            if (p == 0) { // 表示看不见球
                sprintf(command, "(turn 50)"); // 转50度
                sendMessage(command);
                return;
            }
            std::sscanf(p, "(ball) %lf %lf", &ball_distance, &ball_direction);
            // 如果与球的角度相差太大,转向球的方向
            if (ball_direction >5 || ball_direction < -5) { 
                sprintf(command, "(turn %lf)", ball_direction);
                sendMessage(command);
                return;
            }
            // 当球非常远的时候
            if(ball_distance > 13){
                isMove=0; isCatchBall = 0; // 这里是进行防错处理的
            }
            // 当球不近也不远的时候
            if(ball_distance>1 && ball_distance<13){
                sprintf(command, "(dash 200)"); // 冲向球的位置
                sendMessage(command);
                isMove=0; isCatchBall = 0; // 这里是进行防错处理的
                return;
            }
            // 当球很近的时候
            if (ball_distance<1) { // 如果与球的距离小于3
                sprintf(command, "(catch %lf)", ball_direction); //发送catch命令以捕获球
                sendMessage(command);
                isCatchBall = 1; // 抓住球的布尔变量
                return;
            }
        }
        // 抓住球的时候
        if(isCatchBall == 1)
        {   // 如果没有瞬移,先进行瞬移,catch球之后允许瞬移
            if(isMove == 0) // 这个布尔变量是为了防止二次瞬移的
            {  
                sprintf(command, "(move -50 0)");
                sendMessage(command);
                isMove = 1;
                return;
            }
            // 现在开始看门
            double goal_distance = 0; // 门距离
            double goal_dirction = 0; // 门方向
            char *p;
            if(side == 1) p = strstr(msg, "(goal r)"); // 找到门的字符串地址
            else p = strstr(msg, "(goal l)");
            if (p != 0) // 获取门的位置信息
            {
                if(side == 1) std::sscanf(p, "(goal r) %lf %lf", &goal_distance, &goal_dirction);
                else std::sscanf(p, "(goal l) %lf %lf", &goal_distance, &goal_dirction);
                // 踢球!
                sprintf(command, "(kick 100 %lf)", goal_dirction+20); // 朝门的方向踢球
                sendMessage(command);
                isCatchBall = 0;
                isMove = 0;
            }
            else{   // 没看到门,转身看门
                sprintf(command, "(turn 50)");
                sendMessage(command);
            }
            return;
        }
    }
}

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

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


版权声明:本文为qq_40058642原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。