predictedVelocity += (predictedVelocity * moveDir < 0 ? 2*moveDir : moveDir) |
predictedVelocity += (predictedVelocity * moveDir < 0 ? 2*moveDir : moveDir); |
return Math.max(-min, Math.min(value, max)); |
return Math.max(min, Math.min(value, max)); |
That's what I do in PPP and I think that's what Apollon does too, as does RaikoMX and possibly other surfers. -- PEZ |
That's what I do in PPP and I think that's what Apollon does too, as does RaikoMX and possibly other surfers. -- PEZ |
Looks like a strong mini! Way cool. Is it using WaveSurfing? -- PEZ
It is. with the exact movement prediction just to see if the whole thing fits into a mini. -- rozu
Can you share the code for that mini-sized predictor? -- PEZ
Sure. I'll need some time to make it readable...
this is the code I'd use to predict my FuturePosition at the time (getTime() + 10) if I want to go to the point (200, 300) with the well known goTo code somewhere in the run method (I think it should also work for inside the ScannedRobotEvent, though I didn't try it):
double moveAngle = Math.atan2(200 - getX(), 300 - getY()) - getHeadingRadians(); double moveDir = 1; if(Math.cos(moveAngle) < 0) { moveAngle += Math.PI; moveDir = -1; } setAhead(100 * moveDir); setTurnRightRadians(Utils.normalRelativeAngle(moveAngle));
this is the desired piece of code. I'm not using setMaxVelocity?, so it is quiet small. It returns the predicted position.
private Point2D.Double predictPosition() { Point2D.Double predictedPosition = new Point2D.Double(getX(), getY()); double predictedVelocity = getVelocity(); double predictedHeading = getHeadingRadians(); double maxTurning, moveAngle, moveDir; int counter = 1; do { // the movement code basically the same as above moveAngle = Math.atan2(200 - predictedPosition.x, 300 - predictedPosition.y) - predictedHeading; moveDir = 1; if(Math.cos(moveAngle) < 0) { moveAngle += Math.PI; moveDir = -1; } moveAngle = Utils.normalRelativeAngle(moveAngle); // maxTurning is built in like this, you can't turn more then this in one tick maxTurning = Math.PI/720d*(40d - 3d*Math.abs(predictedVelocity)); predictedHeading = Utils.normalRelativeAngle(predictedHeading + limit(-maxTurning, moveAngle, maxTurning)); // this one is nice ;). if predictedVelocity and moveDir have different signs you want to breack down // otherwise you want to accelerate (look at the factor "2") predictedVelocity += (predictedVelocity * moveDir < 0 ? 2*moveDir : moveDir); predictedVelocity = limit(-8, predictedVelocity, 8); // calculate the new predicted position predictedPosition = translatePoint(predicted, predictedVelocity, predictedHeading); } while(++counter < 10); return predictedPosition; } // the math functions used above private static double limit(double min, double value, double max) { return Math.max(min, Math.min(value, max)); } private static Point2D.Double translatePoint(Point2D.Double p, double dist, double ang) { return new Point2D.Double(p.x + dist*Math.sin(ang), p.y + dist*Math.cos(ang)); }
I didn't make any tests so far with exactly this piece of code. please tell me (or correct) if you can see some misbehavior and/or mistakes. -- rozu
Wow. Way cool. I just might try it in Pugilist to see if it works. And if it helps me with my GF1 problem. I can't fit this probably, but it's good to know if it would help. =) -- PEZ
OK, so I tried it. It didn't compile at first, but I managed to fix that. It grew my bot with 200 bytes as I suspected. Unfortunately I didn't get an answer on whether it would help my bot. My reverse destination points are of the battle field for some reason. And I don't understand how to fix it. If you have RobocodeGLV014 you can maybe try yourself to apply this to PugilistGL? It's the destinations calculated inside updateDirectionStats() that I fed your predictor with. Aamzingly simple to apply it when we both thing goTo() style. =) -- PEZ
BTW. This is pretty cool:
Fighting battle 18 ... rz.Apollon 0.2,kawigi.sbf.Barracuda 1.0 RESULT = rz.Apollon 0.2 wins 3358 to 120
-- PEZ
thx, ... . can you send me a version of Pugilist with the above predictor implemented to zuestro@student.ethz.ch. I don't need the GL stuff for this (PugilistGL looks complicated ;)) -- rozu
Eh, I trashed it when I didn't get it to work. But it's easy enough for me to redo it. I'll do it in PugilistGL, because I need it for this. That's how I saw the reverse predicted destinations wasn't on the battle field. Pugilist is as complicated as PugilistGL so it doesn't matter if it comes to that. It'll make a nice demo of the predictor too I think. =) -- PEZ
why is this code so long? if predicting code needs to be this complex, i'm definitely doing something very wrong.--andrew
Sure there are some bytes you could gain if you don't want it to be readable. You also have to make the difference between "absolutely accurate" prediction and "will be more or less the same" prediction. In many cases the code above belongs into the first group. And if you want to be really accurate look here: FuturePosition (this one is a little bit longer). -- rozu
Long? Remove the comments if you like. It's only a few lines of code. And it's hardly complex. What it does is iterate the position of the bot from the current position, using current heading and velocity, to the desired destination point, accounting for acceleration and decceleration and max turn angle at a given velocity. Nothing of that can be discarded if you want to do precise prediction. For something simpler, look at Pugilist, which basicly uses the RandomMovementBot movement for prediction. Of course it's more like "what's my desired destination?" than an actual prediction. -- PEZ
i guess i just don't understand what it does,that's what makes it look complicated to me.--andrew
OK, I'll rephrase that. I mean it's not more complex than the task at hand. It's not trivial to predict your future position accurately. -- PEZ
Wow. I didn't think I'd ever see a minibot at #2 again, even with only 88 battles. :-) Looks like I'm going to have to do some work on Raiko shortly. -- Jamougha
"Wow" is right. --andrew
Thx, but... Just the typical rz.A... bot behavior going up fast and then falling down deep ;). I think it'll stand still somewhere at around 1960 (not a big deal for Raiko). -- rozu
1975 after 400+ battles. I'd say that'll be hard for Raiko unless Jamougha changes strategy for it. -- PEZ
Jim has gotten the above predictor to work. I have plugged it in a bot I call PPP and it makes a world of difference I tell you. Now I'm having spikes near GF-1 as well. =) This is with only the flattener active (that is, no adaption). Looks kinda funny. I'll post yet another profile shot (yaps) on the PPPugilist page. Right now I'm just awaiting Jim's permission to release the bot for test in the rumble. Can you place the above code under the RWPCL umbrella? That would make it clearer what you can and cannot do with the code. You should be the only one allowed to use it for closed source bots I think. -- PEZ
Sure use this code under the licence: "make whatever you want with this code and it would be nice if you give credit" -- rozu
The code above used to find out a future position can probably make a big difference for wave surfers using to goto-style methode, but wave surfers that circle around the enemy (or the position the enemy was when it shot the wave that is nearest to you) cant find out their future position with this piece of code and the current heading precise. What i am doing in my current project ( - which is not yett running - so i should better say what i am trying to do) is to have a function that calculates a referenced move point with wished circle direction, circle center and move step from my current position. So i can simulate my future move - and end position. What i didnt do is to check if the single steps are really possible - i could implement that with the above shown code. Hope one could understand this. --deathcon
That's what I do in PPP and I think that's what Apollon does too, as does RaikoMX and possibly other surfers. -- PEZ