Robocode中一个高效雷达的学习记录

Robocode中一个高效雷达的学习记录

还记的刚接触到Robocode的兴奋,为Robocode比赛准备的艰辛,为写出的第一个机器人而高兴万分,为这个丰富的Robocode世界而震撼不已

Robocode入门的门槛很低,但是要提高着实难度不小,这是我研究Robocode以来的一个不错的收获,作为告别Robocode的献礼,也为纪念我研究Robocode的日日夜夜留下点什么东西。

本雷达代码,提取自中国Robocode第一人,Wave技术的创始人iiley所写的Cigaret机器人中。

http://www.robochina.org,进入了解Robocode

http://sourceforge.net/projects/robocode/files/ 下载Robocode

首先我们来复习Robocode世界中两个很重要的角度系统

注意,我的描述是用度为单位,代码中全使用弧度为单位。

第一,   heading 角度系

 

如图所示,所谓heading角,即从Y轴出发,然后顺时针绕回Y轴的这么个角度区间,取值范围: [0,360]

第二,   bearing角度系

 

所谓bearing 角,即从Y轴顺、逆时针出发,绕半圈回到Y轴所形成的两个角度区间,取值范围:顺时针[0,180 ;逆时针[0,-180]

 

好的,我们已近复习了两角度系,下面我们来学习这个非常高效的雷达。

首先给出代码:

    public void onScannedRobot(ScannedRobotEvent e) {

       //注意 这里的计算都以弧度为单位

       double absBearing=0d;

       //雷达转动角度

       double radarTurnAngle=0d;

       //得到绝对角度差

    absBearing=robocode.util.Utils.normalRelativeAngle(e.getBearingRadians()+getHeadingRadians());

       //根据absBearing角算出Radar要调整的角度

       radarTurnAngle=Math.sin(absBearing - getRadarHeadingRadians());

       //转动雷达,注意是向右

       setTurnRadarRightRadians(radarTurnAngle);

    }

分析实例

 

 

//得到绝对角度差

    absBearing=robocode.util.Utils.normalRelativeAngle(e.getBearingRadians()+getHeadingRadians());

 

说明:

e.getBearingRadians(),如图中的∠FBC所示

是敌机(Enemy)与自己车头方向(你使用setAhead(正值)前进的方向即为车头方向,如BC箭头所示)所成的角,因为是以BCY轴的bearing角,所以这个角在这个例子中是个负值。

 

getHeadingRadians(),如图中∠ABC所示

是以自己的车头方向与屏幕垂直正上方为Y轴所成的heaing

 

absBearing=robocode.util.Utils.normalRelativeAngle(e.getBearingRadians()+getHeadingRadians());

所以absBearing即为FBA,即自己与敌机的连线,与Y轴所成的bearing角,取值范围为[-180,180)

 

//根据absBearing角算出Radar要调整的角度,进过sin运算,这个已经是个修正后的角度了radarTurnAngle=Math.sin(absBearing - getRadarHeadingRadians());

 

 

FBE=absBearing - getRadarHeadingRadians(),在这里计算出来为负值。即雷达需要转动的角度。

最后通过Math.sin(absBearing - getRadarHeadingRadians())进行角度修正得到最终值radarTurnAngle。这个修正很关键,原理可以参照sin曲线图

 

因为setTurnRadarRightRadians(radarTurnAngle)是向右旋转,所以若radarTurnAngle为负则雷达向左旋转。

 

总结

   有以上分析,我们不难得出雷达锁定目标所要转动的角度,由absBearinge.getRadarHeading()(雷达的heading角)来决定.

radarTurnAngle=Math.sin(absBearing-getRadarHeadingRadians());

所以类似的,我们如果想让炮管、车身对准敌机,那么我们就就只要将e.getRadarHeading替换成e.getGunHeading()e.getHeading()即可。

代码如下:

gunTurnAngle=Math.sin(absBearing-getGunHeadingRadians());

bodyTurnAngle=Math.sin(absBearing-getHeadingRadians());

 

 

应用实例:

所以我们可以写成这这样的一个机器人,你可以用它来对付Walls机器人

对,正如它的名字一样,它很疯!

 

import robocode.AdvancedRobot;

import robocode.ScannedRobotEvent;

/**

 * CrazyDog

 * @author lhx

 *

 */

public class CrazyDog extends AdvancedRobot {

    public void run(){

       setAdjustGunForRobotTurn(true);

        setAdjustRadarForGunTurn(true);

        while(true){

          turnRadarRightRadians(5); 

        }

    }

    @Override

    public void onScannedRobot(ScannedRobotEvent e) {

       //注意 这里的计算都以弧度为单位

       double absBearing=0d;

       //雷达转动角度

       double radarTurnAngle=0d;

       double gunTurnAngle=0d;

       double bodyTurnAngle=0d;

       //得到绝对角度差

    absBearing=robocode.util.Utils.normalRelativeAngle(e.getBearingRadians()+getHeadingRadians());

       //根据absBearing角算出Radar要调整的角度

       radarTurnAngle=Math.sin(absBearing - getRadarHeadingRadians());

       gunTurnAngle=Math.sin(absBearing - getGunHeadingRadians());

       bodyTurnAngle=Math.sin(absBearing - getHeadingRadians());

       //转动雷达,注意是向右

       setTurnRadarRightRadians(radarTurnAngle);

       //转动炮管

       setTurnGunRightRadians(gunTurnAngle);

       //转动身体

       setTurnRightRadians(bodyTurnAngle);

       //前进

        setAhead(e.getDistance());

       if(getGunHeat()<0.1)setFire(2);

    }

}

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值