Is this a sensible way to do it?

Jump to navigation Jump to search
Revision as of 11 October 2011 at 16:38.
The highlighted comment was created in this revision.

Is this a sensible way to do it?

My AdvancedRobot, Thor, is currently using a static boolean "scanning" to determine whether to turn the radar or not.

This should provide a degree of locking by setting "scanning" to false when we scan a robot, setting it to "true" after we execute, and turning if it's true.

I know it's a naive approach and doesn't lock very well, but it doesn't appear to lock -at all- currently.

Is it my methodology that's flawed, or should I hunt for a bug in the code? (No point debugging if I'm going about it the wrong way from the start).

    Cbrowne14:20, 11 October 2011

    I think the way most of us do it is to simply scan towards the last known location of the enemy every single tick, making sure we overshoot by a little bit in case they move. I've never put too much effort into radar myself (at least 1v1 radar), because extremely simple solutions tend to work perfectly...

      Skilgannon14:47, 11 October 2011
       

      You need to turn it every tick, it's just a question of clockwise or counter-clockwise. The area covered by the sweep of the radar from last tick to this tick is the area that is scanned. So once you scan, you want to reverse the direction you turn the radar, not stop turning it.

      Edit: Also, there's an option in Robocode to display the radar arcs, which would help you see exactly what's going on.

        Voidious14:59, 11 October 2011
         

        Ah, so I need to refactor "scanning" to function more as a "turn radar left" boolean (if true, turn radar left, if false turn right) and then just toggle it when I find a robot, would that work?

          Cbrowne15:02, 11 October 2011
           

          Yep, that would work fine. That kind of scan type is known as an 'Infinity lock' - there's more on it here: One_on_One_Radar. That kind of radar algorithm will skip scans occasionally, so there are a few others on that page which are usually used on bots that aren't in severely limited codesize tournaments. Personally, I recommend the 'turn multiplier lock', it works perfectly and is quick and easy to implement.

            Skilgannon16:01, 11 October 2011
             
            Edited by another user.
            Last edit: 16:57, 11 October 2011

            Wow, that one is excellent. I'm not quite grokking it yet, but experiments have shown that it performs much smoother than my previous implementation.

            Now to get the gun to point in the right direction.

            I've implemented a function, "turnGunTo" which (in theory) turns the gun to a given (absolute) heading. I'm struggling to get it to work, though, as the gun just appears to spin continuously. Here's my function:

            	public void turnGunTo(double newHeading) {
            		double oldHeading = getGunHeadingRadians(); 
            		// use of normalRelativeAngle means we don't have to decide left or right
            		setTurnGunLeft(Utils.normalRelativeAngle(calculateTurnAmount(newHeading,oldHeading)));
            	}
            

            And, for reference, the calculateTurnAmount() function:

            	public double calculateTurnAmount(double newHeading,double oldHeading) {
            		// turn amount is a segment of a full circle, calculated by (circle - leftAngle) + rightAngle;
            		return (FULL_CIRCLE - Math.max(newHeading, oldHeading)) + Math.min(newHeading, oldHeading);
            	}
            

            What am I doing wrong? Also, is the method abstraction superfluous? It seems so, but in some ways it makes it a little bit more semantically-obvious what I'm trying to achieve.

              Cbrowne16:55, 11 October 2011
               

              I think rather just go with this:

              	public void turnGunTo(double newHeading) {
              		double oldHeading = getGunHeadingRadians(); 
              		// use of normalRelativeAngle means we don't have to decide left or right
              		setTurnGunLeft(Utils.normalRelativeAngle(newHeading-oldHeading));
              	}
              

              You can even move the getGunHeadingRadians() into the brackets if you want, and get rid of oldHeading, although that might be going a bit far =). Utils.normalRelativeAngle() will automatically clean up the full circle/double circle/no circle thing for you.

              It might be setTurnGunRight though... you'll have to check.

                Skilgannon17:01, 11 October 2011
                 

                Well the reason I was using oldHeading was because it was originally passed into turnGunTo, but since it's called turnGunTo, and therefore only ever applies to the Gun, I realised I could [read: should] get the value inside the function itself.

                Shouldn't it be setTurnGunLeftRadians() (or setTurnGunRightRadians())?

                I'm still working on checking which one I want, and what value I want to pass into it (currently calling it with:

                turnGunTo(Utils.normalRelativeAngle(getGunHeadingRadians() - e.getBearingRadians())); 
                

                inside my onScannedRobot() function)

                You're being uncharacteristically helpful for a random stranger on the internet. Am I supposed to give you cookies or something? :)

                  Cbrowne17:18, 11 October 2011
                   

                  Ah yes, it should be radians.

                  I suggest you read up on e.getBearingRadians() - I think it returns something relative to what your getHeadingRadians() returns. So the absolute bearing from you to your enemy would be getHeadingRadians() + e.getBearingRadians(), which (I think) is what you need to call your turnGunTo function with.

                  And you don't need to give me a cookie, just work on your bot and provide some more competition =) I might also be procrastinating for my final B.Eng. thesis - it's due in 2 weeks ;-)

                    Skilgannon17:38, 11 October 2011