收藏 分销(赏)

我的第一个机器人足球程序.doc

上传人:xrp****65 文档编号:7231524 上传时间:2024-12-28 格式:DOC 页数:12 大小:43.50KB 下载积分:10 金币
下载 相关 举报
我的第一个机器人足球程序.doc_第1页
第1页 / 共12页
我的第一个机器人足球程序.doc_第2页
第2页 / 共12页


点击查看更多>>
资源描述
// Strategy.cpp : Defines the entry point for the DLL application #include "stdafx.h" #include "Strategy.h" #include <math.h> BOOL APIENTRY DllMain( HANDLE hModule,                          DWORD    ul_reason_for_call,                          LPVOID lpReserved         ) {       switch (ul_reason_for_call) {     case DLL_PROCESS_ATTACH:     case DLL_THREAD_ATTACH:     case DLL_THREAD_DETACH:     case DLL_PROCESS_DETACH:      break;       }       return TRUE; } //global variables const double PI = 3.1415926; int WHO = 1; //1 blue 0 yellow const double MAXL = 112; //球场对角线长 FILE *DEBUGFILE; //调试文件 Environment *ENV; int NEEDROTATE[5] = {1, 1, 1, 1, 1}; //1 need, else not need int PD[5] = {0}; //巡逻方向,由 点 1 到 2 double TRACE[6][2][2] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; //纪录 5 个机器人的轨迹 double DISPLACEMENT[6] = {0}; //纪录每个机器人在 1/6 秒内的位移 int EV[6] = {0}; //estimate v 估计的机器人的速度 and the ball double COUNT1 = 0, COUNT2 = 0; //保存调用次数 double PBP[2] = {0, 0}; //预测的球的坐标 predict ball position int WIB = 5; //whree is ball double ROBOTLENGTH = 3.2; //length of a robot //basic methods void go(Robot *robot, int rID, const double x, const double y); //朝某点运动 void backGo(Robot *robot, int rID, const double x, const double y); // double rotateTo(Robot *robot, int rID, const double desX, const double desY); //转动 void stop(Robot *robot, int rID); //停止 void to(Robot *robot, int rID, double x, double y); //到某点静止 void backTo(Robot *robot, int rID, double x, double y); //反向到某点静止 void estimateV(); //估计所有机器人的速度,and the ball void predictBall(double s); //预测球的出现 void run(Robot *robot, int rID, int vl, int vr); //advanced methods void passBall(Robot *robotS, Robot *robotG, int rIDS, int rIDG); //传球 robot send ,robot get void patrol(Robot *robot, int rID, double x1, double y1, double x2, double y2); //在 2 点间晃动 void nearBall(Robot *robot, int rID, double x, double y); //接近球,并且与 x,y 不在球的同一边 void kickBall(Robot *robot, int rID, double x, double y); //把球打到指定地点 //stratgies bool canKShoot(Robot *robot, int rID);//是否可以用头撞球进 can kick shoot bool canRShoot(Robot *robot, int rID); //是否可以旋转撞球进 rotate int whereIsBall(); //判断球在哪个区域,返回区域编号 bool hasEnemyBetween(Robot *robot, double x, double y); //is there enemy between robot and x,y void defend(int wib); // void attack(int wib); // //role controller void waiter(Robot *robot, int rID, double x, double y); //在 x,y 点等待球,一旦 r.x>x,距离小于某值时kick ball void activeDefender(Robot *robot, int rID); //绕到球的右边 kick ball void negativeDefender(Robot *robot, int rID, double x, double y); //首在某点并对着球,一旦距离小于某一值 kick ball,b.x > x void keepHelper(Robot *robot, int rID); //协助守门员在球门的另一半守门,x 坐标小于守门员 void keeper(Robot *robot, int rID); //守门员,在固定 x 坐标跟着球的 y 坐标跑 void attacker(Robot *robot, int rID); //绕到球的右边 kick ball //strategy for all states void strategyForD(Environment *env); //default void strategyForFB(Environment *env); void strategyForPlK(Environment *env); void strategyForPeK(Environment *env); void strategyForFK(Environment *env); void strategyForGK(Environment *env); extern "C" STRATEGY_API void Create ( Environment *env ) { // allocate user data and assign to env->userData // eg. env->userData = ( void * ) new MyVariables (); } extern "C" STRATEGY_API void Destroy ( Environment *env ) { // free any user data created in Create ( Environment * ) // eg. if ( env->userData != NULL ) delete ( MyVariables * ) env->userData; } extern "C" STRATEGY_API void Strategy ( Environment *env ) { //here are my Strategies ,as the game state differes calls the responding method COUNT2 ++; ENV = env; estimateV(); switch(env->gameState){     case 0 : strategyForD(env);break;     case FREE_BALL : strategyForD(env); break;     case PLACE_KICK : strategyForD(env); break;     case PENALTY_KICK : strategyForPeK(env); break;     case FREE_KICK : strategyForD(env); break;     case GOAL_KICK : strategyForD(env); break; } } void strategyForD(Environment *env){ //对默认情况 // double bx,by ,rx; //ball's coordinate int lt = 0; bx = env->currentBall.pos.x; by = env->currentBall.pos.y; rx = env->home[0].pos.x; whereIsBall(); //to(&env->home[3], 3,env->currentBall.pos.x, env->currentBall.pos.y); //negativeDefender(&env->home[2],2,0,58); //activeDefender(&env->home[1],1); //activeDefender(&env->home[2],2); //activeDefender(&env->home[3],3); //attacker(&env->home[4],4); keeper(&env->home[0],0); switch(WIB){     case 1 : defend(1); break;     case 2 : defend(2); break;     case 3 : defend(3); break;     case 4 : attack(4); break;     case 5 : attack(5); break;     case 6 : attack(6); break;     case 7 : attack(7); break;     case 8 : attack(8); break;     case 9 : attack(9); break; } //以下相当于紧急模块 if(bx > 88.28 && by > 33.93 && by < 52.92 && rx-bx>-0.5)     go(&env->home[0], 0, bx-0.3, by); for(lt=0;lt<5;lt++){     if(canKShoot(&env->home[lt], lt) && env->home[lt].pos.x < 27)      go(&env->home[lt],lt,bx,by); } } void strategyForFB(Environment *env){ //对 freeball // } void strategyForPlK(Environment *env){ // } void strategyForPeK(Environment *env){ // double bx,by; //,rx,ry; //rx = env->home[3].pos.x; //ry = env->home[3].pos.y; bx = env->currentBall.pos.x; by = env->currentBall.pos.y; if(env->whosBall ==1){     //     if(env->opponent[0].pos.y > 43.00){      rotateTo(&env->home[3],3,6.8, 33.0);      if(NEEDROTATE[3] != 1)       go(&env->home[3],3,bx,by);     } } else if(env->whosBall ==2)     keeper(&env->home[0], 0); } void strategyForFK(Environment *env){ // } void strategyForGK(Environment *env){ // } void go(Robot *robot, int rID, const double x, const double y){ // double toX, toY; int vl,vr; //轮速 toX = x; toY = y; vl = 125; vr = 125; rotateTo(robot, rID, toX, toY); if(NEEDROTATE[rID] != 1){     robot->velocityLeft = vl;     robot->velocityRight = vr; } } void backGo(Robot *robot, int rID, const double x, const double y){ // double toX, toY; int vl, vr; vl = vr = -125; toX = robot->pos.x +(robot->pos.x - x); toY = robot->pos.x +(robot->pos.y - y); rotateTo(robot, rID, toX, toY); if(NEEDROTATE[rID] != 1){     robot->velocityLeft = vl;     robot->velocityRight = vr; } } void to(Robot *robot, int rID, double x, double y){ // 调用前要把 NEEDROTATE 置 1,给每个机器人保存一个 NEEDROTATE ?? //是否先要停止机器人 double length; //机器人离目的点的距离 double dx, dy; int lt; int vBest[6] = {30, 50, 60, 70, 100, 125}; // 最适合的速度对不同的距离 double l = 3; //允许的误差 double beta; dx = robot->pos.x - x; dy = robot->pos.y - y; length = sqrt(dx*dx + dy*dy); lt = int(length/MAXL*6); beta = rotateTo(robot, rID, x, y); rotateTo(robot, rID, x, y); if(NEEDROTATE[rID] != 1){     run(robot, rID, vBest[lt-1], vBest[lt-1]);     if(length < l+ 4)      run(robot, rID, 22, 22);     if(length < l+2)      run(robot, rID, 16, 16);     if(length < l)      run(robot, rID, 11, 11);     if(length < 2)      run(robot, rID, 7, 7);     if(length < 1)      run(robot, rID, 4, 4);     if(length < 0.7)      run(robot, rID, 2, 2);     if(length < 0.4)      run(robot, rID, 1, 1);     if(length < 0.2)      run(robot, rID, 0, 0); } } void backTo(Robot *robot, int rID, double x, double y){ //实验后误差为    2 int ve = 30; //速度误差 double le = 3; //距离控制速度 double dx, dy, length; double ox, oy; //x,y 关于机器人对称的点 int vk = 0; int v[5] = {-30, -50, -70, -90, -120}; dx = robot->pos.x- x; dy = robot->pos.y - y; length = sqrt(dx*dx + dy*dy); ox = robot->pos.x + dx; oy = robot->pos.y + dy; if(length >= 100)     length = 99; vk = int(length/20); if(rotateTo(robot, rID, ox, oy), NEEDROTATE[rID] == 1)     rotateTo(robot, rID, ox, oy); else{     if(length > 10)      run(robot, rID, v[vk], v[vk]);     else if(length > le)      run(robot, rID, -15, -15);     else if(length > 0.1)      run(robot, rID, 0, 0); } } double rotateTo(Robot *robot, int rID,const double desX, const double desY){ //给出某个目的点后转角 //整个转动过程都要考虑机器人和目的点始终是运动的 double alpha; //机器人与目的点的连线与标准角度系统成的角,即从正 X 轴转到该直线成的角 double length; //两点间的距离 double sinValue; //alpha 的 sin 值 int direction; //旋转方向1 为顺时针,-1 为逆时针 double aRRobot,aR; //机器人和直线在 0-360 的角度坐标系中的角度,abuslote rotation double dy; //目的点与机器人的 y 坐标差的绝对值 double beta; //机器人轴线与线的最小夹角 int v; //速度 double vk, k2 = 87; //速度修正,k2 是二次模型的系数 int error[6] = {30, 20, 15, 13, 11 ,9}; //允许误差分为 6 个等级,选取的策略很多。。 int curError; //当前允许的误差 int ll; //记数器 vk = 1; //速度修正为 1 length = sqrt((robot->pos.x - desX) * (robot->pos.x - desX) + (robot->pos.y - desY) * (robot->pos.y - desY)); dy = desY - robot->pos.y; if(dy < 0)     dy = dy*-1; sinValue = dy/length; if(sinValue >1)     sinValue = 1; if(sinValue < -1)     sinValue = -1; //防止由于计算误差导致的溢出 alpha = asinf(sinValue)/PI * 180; //asin 的返回值是弧度!! if((desY < robot->pos.y) && (desX < robot->pos.x)) //左下     alpha = -180 + alpha; else if((desY < robot->pos.y) && (desX > robot->pos.x)) //右下     alpha = -alpha; else if((desY > robot->pos.y) && (desX < robot->pos.x)) //左上     alpha = 180 - alpha; else if((desY > robot->pos.y) && (desX > robot->pos.x)) //右上     alpha = alpha; else if((desY == robot->pos.y) && desX < robot->pos.x) //左     alpha = 180; else if((desY == robot->pos.y) && desX > robot->pos.x) //右     alpha = 0; //把角转化为系统角度 if(robot->rotation < 0 )     aRRobot = 360 + robot->rotation; else     aRRobot = robot->rotation; if(alpha < 0)     aR = 360 + alpha; else     aR = alpha; //把角转化为0-360坐标系中角度 beta = fabs(aRRobot - aR); //计算夹角 if(aRRobot - aR >0 && beta < 180)     direction = 1; if(aRRobot - aR >0 && beta > 180)     direction = -1; if(aRRobot - aR <0 && beta < 180)     direction = -1; if(aRRobot - aR <0 && beta > 180)     direction = 1; //计算旋转方向 if(beta > 180)     beta = 360 - beta; else     beta = beta; //如何在符合运动学的情况下精确控制机器人的转角 ?? v = int(beta/180*60-vk); //线性模型,应该有其他更好的模型 //v = sqrt(k2* beta) - vk; //二次模型,经实验没有线性的好 if(v < 0) //速度控制     v= 0; if(v> 60)     v = 60; if(v > 20)     v = 60; if(direction == 1){     run(robot, rID, int(0.3*EV[rID])+v, int(0.3*EV[rID])-v); } else if(direction == -1){     run(robot, rID, int(0.3*EV[rID])-v, int(0.3*EV[rID])+v); } //选取误差限 for(ll = 0; ll < 6; ll++){     if(length >= MAXL/6*(ll) && length < MAXL/6*(ll +1))      curError = error[ll]; } //应该根据距离的远近选取允许误差的大小,越远允许误差越小 //是先计算需要转还是先发轮速指令 if(beta > curError) //误差小于 curError 度     NEEDROTATE[rID] =1; else     NEEDROTATE[rID] = 0; //在误差限度内可以不再转 return beta; //这个控制有待根据实验数据改进 } void stop(Robot *robot, int rID){ // int vReduce[6] = {-3, -10, -20, -30, -40, -50}; int lt = 0; lt = int(EV[rID]/20); robot->velocityLeft = vReduce[lt]; robot->velocityRight = vReduce[lt]; if(EV[rID] < 4){     robot->velocityLeft = 0;     robot->velocityRight = 0; // 要根据试验改 } } void estimateV(){ // double dx, dy; double k; //位移对于速度的系数 v= k*s int ym = 0; k = 6.8; //k 由试验测得 10/1.47符合的很好对 50 100 也 if(TRACE[0][0][0] == -1){     for(ym = 0; ym < 5; ym++){      TRACE[ym][0][0] = ENV->home[ym].pos.x;      TRACE[ym][0][1] = ENV->home[ym].pos.y;      TRACE[ym][1][0] = ENV->home[ym].pos.x;      TRACE[ym][1][1] = ENV->home[ym].pos.y;     }     TRACE[5][0][0] = ENV->currentBall.pos.x;     TRACE[5][0][1] = ENV->currentBall.pos.y;     TRACE[5][1][0] = ENV->currentBall.pos.x;     TRACE[5][1][1] = ENV->currentBall.pos.y; } if(COUNT2 - COUNT1 >= 10){ //每调用 10 次纪录坐标     for(ym = 0; ym < 6; ym++){      dx = TRACE[ym][1][0] - TRACE[ym][0][0];      dy = TRACE[ym][1][1] - TRACE[ym][0][1];      DISPLACEMENT[ym] = sqrt(dx*dx + dy*dy);      TRACE[ym][0][0] = TRACE[ym][1][0];      TRACE[ym][0][1] = TRACE[ym][1][1];      EV[ym] = int(DISPLACEMENT[ym]*k); //用什么模型?     }     COUNT1 = COUNT2; } else{     for(ym = 0; ym < 5; ym++){      TRACE[ym][1][0] = ENV->home[ym].pos.x;      TRACE[ym][1][1] = ENV->home[ym].pos.y;     }     TRACE[5][1][0] = ENV->currentBall.pos.x;     TRACE[5][1][1] = ENV->currentBall.pos.y; } } int whereIsBall(){ // double x1, x2, y1, y2; //界限 double x, y; int k; //区域代号基数 int re; //result x1 = 37.2016; x2 = 70.2706; y1 = 33.7197; y2 = 58.5660; x = ENV->currentBall.pos.x; y = ENV->currentBall.pos.y; if(x > x2)     k = 0; else if(x <= x2 && x>= x1)     k = 3; else if(x < x1)     k= 6; if(y < y1)     re =    3 + k; else if(y >= y1 && y <= y2)     re = 2 + k; else if(y > y2)     re = 1 + k; WIB = re; return re; } bool hasEnemyBetween(Robot *robot, double x, double y){ /* double dx, dy, k; double rx, ry, temp; //robot.x, robot.y double yc; //yc = f(enemyRobot.x) bool re; //result int lt; dx = robot->pos.x - x; dy = robot->pos.y - y; rx = robot->pos.x; ry = robot->pos.y; if(x > rx){     temp = rx;     rx = x;     x = temp; } if(y > ry){     temp = ry;     ry = t;     y = temp; } for(lt = 0; lt < 5; lt++){     if(ENV->opponent.pos.x < x && ENV->opponent.pos.x > rx)      re = false; } if(dx < 0.2){ } else if(dy < 0.2){ } else{     k = dy/dx;     yc } */ return false; //should be re } double f(double k, double x0, double y0, double x){ // return k*x - k*x0 + y0;
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 百科休闲 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服