gametechmods

Robot Arena => Modifications => Topic started by: Clickbeetle on March 19, 2010, 08:35:13 PM

Title: An RPM-monitoring AI
Post by: Clickbeetle on March 19, 2010, 08:35:13 PM
This is something that's been on my to-do list ever since apanx made his melty brain AI, and I've finally got around to finishing it.  It's an AI that measures the RPM of its spinning weapons, and won't move until they're spinning at a certain speed.


Get it here: https://gametechmods.com/uploads/files/SpinupOmni2.zip (https://gametechmods.com/uploads/files/SpinupOmni2.zip)


Directions for using it are at the top of the .py file.  One thing you should know that I might as well repost here: RA2 can't measure times less than 1/30 second, even if you set the tick interval lower.  So the RPM calculator is fairly limited.  It can't measure anything faster than 1500 RPM, and it gets less accurate the faster a bot's weapons are spinning.  It still works pretty well for most bots, though--it turns out that spinners in RA2 are generally pretty slow, even in DSL.


One cool feature is if you put 'DisplayRPM':1 in the Bindings, you get an in-game display that shows the current RPM of the bot's spinner, the maximum RPM, and the average RPM over the whole match.  If you've ever wanted to know how fast Diarrhea Of A Madman's weapon spins, now you can find out.


Corollary: the 1/30 second limit also means that apanx's FBS.py uses an unnecessarily low tick interval.  It should be able to be increased from 0.001 to 0.0333 with no loss in performance, thus decreasing lag.
Title: Re: An RPM-monitoring AI
Post by: Madiaba on March 19, 2010, 08:39:49 PM
Cool tweek.
Where'd you decide to put the display box?  Where the usual debug stuff displays?
Do you enter the motor # in the Bindings line so it knows which motor to monitor?
Can it do servos?

I'll try it out this weekend.  And then maybe read the directions,,, hehe.
Title: Re: An RPM-monitoring AI
Post by: Clickbeetle on March 19, 2010, 08:44:55 PM
The RPM display is in the upper left corner, as usual.


The motor ID is set in the Bindings.  'MotorID' and 'Motor2ID' for a second motor (the AI can monitor up to 2)


And yes it can do servos, since all it does is GetMotorAngle and count how long it takes to make 3/4 of a revolution.
Title: Re: An RPM-monitoring AI
Post by: Madiaba on March 19, 2010, 09:24:04 PM
CB, I was just thinking:

1. Moding your coding to monitor the weapon(s) spin motor(s), and do not tell the bot to attack (or even some evasive tactic),...till weapons are up to speed...

2. Or monitor your opponent's weapon's motor speed,....
 and if tooo hairy, head for the hills till situation improves (hits a wall, another bot,...).
Title: Re: An RPM-monitoring AI
Post by: Clickbeetle on March 19, 2010, 09:27:58 PM
CB, I was just thinking:

1. Moding your coding to monitor the weapon(s) spin motor(s), and do not tell the bot to attack (or even some evasive tactic),...till weapons are up to speed...


That's what it does.  The AI sits still until the weapon reaches some target RPM set in Bindings.  Your Evade tactic isn't done yet is it?  Otherwise that would be another good option.
Title: Re: An RPM-monitoring AI
Post by: JoeBlo on March 19, 2010, 09:43:48 PM
very cool and might be usful for all the spinner robots in Backlash (credit issued to yourself of coarse)

Oh and why I think of it, you should use it for hypnodisc in DSL 3 since in real life it was there strategy to move slow until the weapon was up to speed  ;)
Title: Re: An RPM-monitoring AI
Post by: Naryar on March 20, 2010, 04:28:37 AM
Excellent ! This is going to seriously help the spinner world.

Hell, it might even be possible to calculate the spinning speed of a SnS...

Edit: OMG THIS IS AWESOME we can calculate ANY SPEED on ANY BOT if we designate drive motors !

(AKA dividing the RPM's of a wheel by her perimeter)
Title: Re: An RPM-monitoring AI
Post by: Madiaba on March 20, 2010, 10:10:07 AM
Nar, cool idea. An FBS's RPM could be calculated by tracking the bot's heading/direction to the arena, and thus it's rotations.  Then calculate, and display.
 
CB, Nice then.  I'll check it out.... 
As for my 'Evade' tactic, I've only had time to bring it to a rudimentary stage that works ok, but not sophisticated at all.  Trov took my skeletal work and fleshed it out nicely, IMHO.  I haven't talked with him in a week or two, so I don't know where he's at with it.  I'll talk with him.  Would be nice to 'evade' until your up and 'ready for battle'...
 
Title: Re: An RPM-monitoring AI
Post by: Jack Daniels on March 20, 2010, 11:57:59 AM
You guys are amazing at figuring this stuff out. 
Title: Re: An RPM-monitoring AI
Post by: LiNcK on March 20, 2010, 12:06:37 PM
You guys are amazing at figuring this stuff out.

QFT!! ;D
 
I have no idea how u guys do this, But soon AIs will drive better than real people O_O
Title: Re: An RPM-monitoring AI
Post by: Squirrel_Monkey on March 20, 2010, 12:07:33 PM
But soon AIs will drive better than real people O_O
My AI already does, e.g. FBS,py
Title: Re: An RPM-monitoring AI
Post by: SKBT on March 20, 2010, 11:33:25 PM
So does this mean that we could see the real flipper tactic of ram with the back to slow down a spinner then turn around and fire the flipper?
Title: Re: An RPM-monitoring AI
Post by: Naryar on September 21, 2010, 03:33:43 AM
*downloads*

I'm going to try and implement a RPM-measuring thing in Omni.py

Edit: lol it already is in NAR AI :P
Title: Re: An RPM-monitoring AI
Post by: JoeBlo on September 21, 2010, 04:28:19 AM
:O Awesomez Bumpage Dude
Title: Re: An RPM-monitoring AI
Post by: Naryar on September 21, 2010, 05:33:20 AM
:O Awesomez Bumpage Dude

*clenches fist*

Don't you think an awesome thread needs awesome bumps ?

Plus by bumping this I hopefully make people read the thread more, hence am advertising for your master...

...and you still complain ?  :ermm:
Title: Re: An RPM-monitoring AI
Post by: JoeBlo on September 21, 2010, 05:46:14 AM
what made you think I was complaining mr angry  :gawe:
Title: Re: An RPM-monitoring AI
Post by: Naryar on September 21, 2010, 05:51:15 AM
what made you think I was complaining mr angry  :gawe:

Hmm. There are various reasons... may be my slight paranoia, may be because you do like to pick on me, or maybe something else ?

*happily off topic*
Title: Re: An RPM-monitoring AI
Post by: JoeBlo on September 21, 2010, 06:14:31 AM
yeah probably should get back on topic :P

sorry if I do pick on you.. I don't mean to convey such image, only having fun.. you seem to react more then other people :P

so when you say already in NarAI you mean the edited omni or Clicks original one ?
Title: Re: An RPM-monitoring AI
Post by: Naryar on September 21, 2010, 06:49:47 AM
sorry if I do pick on you.. I don't mean to convey such image, only having fun.. you seem to react more then other people :P

It is fine. I enjoy clashing with people (well sometimes at least :P). But yes, it's not really fitting to your "nice guy" position !

so when you say already in NarAI you mean the edited omni or Clicks original one ?

Click's original one. I started an OmniPlus project but abandoned quickly.

But this AI is complicated, and i do not know much about python. I'll try nevertheless.
Title: Re: An RPM-monitoring AI
Post by: JoeBlo on September 21, 2010, 07:03:24 AM
I might have a go if you dont work it out... could be a useful backlash AI :P
Title: Re: An RPM-monitoring AI
Post by: apanx on September 21, 2010, 12:43:13 PM
Corollary: the 1/30 second limit also means that apanx's FBS.py uses an unnecessarily low tick interval.  It should be able to be increased from 0.001 to 0.0333 with no loss in performance, thus decreasing lag.

Short version: There is no 1/30th second limit for the game.

Long version: While the getTimeElapsed() only have a resolution of about 1/30th second. The game tries to execute code as fast as the specified tickInterval. When tickInterval is set too low, stuttering occurs as there are not enough processing resources to excecute all instructions fast enough to finish them before the tickInterval is over in the real world. In order to get a higher limit for the RPM measurement, you would have to write your own time measurement code as the resolution of getTimeElapsed() is not enough. Something like the example below.

Code: [Select]
        #Measure RPM
        if (self.GetMotorAngle(self.motorID) > math.pi/3 or self.GetMotorAngle(self.motorID) < 0) and self.measuring == 0:
              self.revolution += self.tickInterval
            self.measuring = 1
         
        if self.measuring == 1:
            self.revolution += self.tickInterval
       
        if 0 < self.GetMotorAngle(self.motorID) < math.pi/3 and self.measuring == 1:
            self.RPM = 50 / self.revolution
            self.revolution = 0
            if self.display != 0:
                self.RPMhist.append(self.RPM)
                if self.RPM > self.max_RPM:
                    self.max_RPM = self.RPM
            self.measuring = 0
Title: Re: An RPM-monitoring AI
Post by: Somebody on September 21, 2010, 12:45:33 PM
apanx :D
Title: Re: An RPM-monitoring AI
Post by: Serge on September 21, 2010, 05:32:23 PM
Code: [Select]
self.revolution += plus.AI.__getattr__tickInterval__(self)

Why would you do such a horrible thing? Provided self is actually a plus.AI instance:

Code: [Select]
self.revolution += self.tickInterval
Title: Re: An RPM-monitoring AI
Post by: Badnik96 on September 21, 2010, 05:54:37 PM
apanx :D
Title: Re: An RPM-monitoring AI
Post by: Clickbeetle on September 21, 2010, 09:23:20 PM
*downloads*

I'm going to try and implement a RPM-measuring thing in Omni.py

Edit: lol it already is in NAR AI :P


SpinupOmni2 already has all the capabilities of Omni.  Adding RPM measurement to Omni would just be basically reinventing the wheel. :P


@apanx: Awesome!  Why didn't I think of doing that?  Such a simple solution...


Now maybe I can make the RPM calculator more accurate.


On a side note, although the 1/30 second cap seems not to apply to apanx's FBS.py, a tick interval of 1/30 second does seem to work just as well as 1/1000.  However, just in case, I implemented some code into my reduced-lag version that lets you set the tick interval in Bindings.  Just add 'Ticks':x to the bot's AI, where x is how much to divide the default tick interval.  So 'Ticks':2 halves the tick interval to 1/16 second, and 'Ticks':3.75 makes it 1/30 second.
Title: Re: An RPM-monitoring AI
Post by: apanx on September 22, 2010, 09:03:21 AM
Code: [Select]
self.revolution += plus.AI.__getattr__tickInterval__(self)

Why would you do such a horrible thing? Provided self is actually a plus.AI instance:

Code: [Select]
self.revolution += self.tickInterval

Nice, that works too, I figure this is a more elegant way to do this. Used the old code because the tickInterval attribute did not show up when doing a dir() on plus.AI.
Title: Re: An RPM-monitoring AI
Post by: Serge on September 22, 2010, 05:07:55 PM
Used the old code because the tickInterval attribute did not show up when doing a dir() on plus.AI.

Protip: do someObject.__dict__ next time :P.
Title: Re: An RPM-monitoring AI
Post by: GroudonRobotWars on September 23, 2010, 07:05:20 PM
Would this work for Hypno-Disc?
Title: Re: An RPM-monitoring AI
Post by: Clickbeetle on September 25, 2010, 09:00:07 PM
It will work for any spinner.  You only need to know the ID of the spin motor.
Title: Re: An RPM-monitoring AI
Post by: Clickbeetle on October 04, 2010, 12:04:35 AM
So, I've tried to improve the RPM calculator.  And it still seems to have a resolution of only 1/30 second.  I've tried this:


Code: [Select]

        #Measure RPM
        if (self.GetMotorAngle(self.motorID) > math.pi/3 or self.GetMotorAngle(self.motorID) < 0) and self.measuring == 0:
            self.revolution = 0
            self.measuring = 1
           
        if self.measuring == 1:
            self.revolution += self.tickInterval
           
        if 0 < self.GetMotorAngle(self.motorID) < math.pi/3 and self.measuring == 1:
            self.RPM = 50/self.revolution
            if self.display != 0:
                self.RPMhist.append(self.RPM)
                if self.RPM > self.max_RPM:
                    self.max_RPM = self.RPM
            self.measuring = 0


Basically what apanx posted.  But it has the same problem as the old code.  It only goes up to about 1500 RPM, and the accuracy decreases the faster the motor goes.


So then I tried totally rewriting it.  Rather than measure the number of ticks it takes to make a revolution, I measured how far the motor turns in one tick.  In theory, this should be much more precise than the way I had it before, especially at high speeds.


Code: [Select]

        #Measure RPM
        #looping timer for RPM calculation
        self.measuring += 1
        if self.measuring > 1:
            self.measuring = 0
           
        if self.measuring == 1:
            self.angle2 = self.GetMotorAngle(self.motorID)
            #correct for pi/-pi transition area
            if self.angle1 > 0 and self.angle2 < 0 and self.spindir == 1:
                self.angle2 += math.pi*2
            if self.angle1 < 0 and self.angle2 > 0 and self.spindir == 0:
                self.angle1 += math.pi*2
            self.RPM = (abs(self.angle2 - self.angle1)/(math.pi*2))*(60/self.tickInterval)
            if self.display != 0:
                self.RPMhist.append(self.RPM)
                if self.RPM > self.max_RPM:
                    self.max_RPM = self.RPM
           
        if self.measuring == 0:
            self.angle1 = self.GetMotorAngle(self.motorID)


But now, if the tick interval is any shorter than 1/30 second, the calculator frequently returns 0.0 RPM, meaning that it thinks angle1 and angle2 are exactly the same.  (Interestingly, it sometimes returns 0.0 RPM and also double of normal RPM when the tick interval is longer than 1/30 second, though much less frequently).  The only explanation I can think of for this is that RA2 only moves at a frame rate of 30 FPS, so if you try to measure the motor angle more than once in the same frame, you get the same angle and thus an RPM of 0.


So it appears there is no way to overcome the 1/30 second limit, unless I'm missing something here.  Still, this new RPM calculator should be more accurate for speeds closer to 1500 RPM, if I can only get it to work consistently.  As I said, it periodically returns 0 or double RPM's, and the RPM also seems dependent on the tick interval (it returns slightly higher RPM's with shorter tick intervals on the same bot).
Title: Re: An RPM-monitoring AI
Post by: Madiaba on October 04, 2010, 12:46:42 AM
This looks very interesting, CB.  I wish I could dabble here, but my fast comp is still in boxes...somewhere.  But for now I was thinking of a few more possible uses of this code:
-Rev limiter (use?)
-Rev reducer (in case of loss of weapon/stability)
-Motor 'stall' checker (if stall, then have bot disengage, spin up and then re-engage enemy)
-Rev 'failure' checker (if 'chronically' not able to get weapon motor up to certain attack-parameter rpm, then change tactic [i.e. to 'Ram'])
 
 
Title: Re: An RPM-monitoring AI
Post by: Clickbeetle on October 04, 2010, 01:16:03 AM
-Rev reducer (in case of loss of weapon/stability)


Great idea!  I already have a stall checker, but I didn't think of this.


Oh wait... that would actually be possible to do without the RPM calculator.  Just use an analog and tell it to input at half power when it loses weapons or something.  Still a good idea though.
Title: Re: An RPM-monitoring AI
Post by: Madiaba on October 04, 2010, 08:37:37 AM
-Rev reducer (in case of loss of weapon/stability)


Great idea!  I already have a stall checker, but I didn't think of this.


Oh wait... that would actually be possible to do without the RPM calculator.  Just use an analog and tell it to input at half power when it loses weapons or something.  Still a good idea though.
Ok, but reducing motor input to 50% doesn't guarantee it's even turning, when this coding would check and could ensure that factor.
 
This is one thing I really like about this coding- you know what the motor is 'actually' doing. It could be set like a 'governor' on a Briggs and Stratton small motor, that adds or removes throttle in an effort to both maintain rotation, and at a certain rate.
 
*Finds self plowing through boxes...*
 
 
 
BTW: I'm tempted to start a "Python" thread where the code could be put in one place for Tutelage and Reference.  Maybe a whole board...  I think Trov wouldn't mind Moderating it...
 
 
 
 
 
Title: Re: An RPM-monitoring AI
Post by: Serge on October 07, 2010, 03:37:22 PM
To get a higher resolution time delta:

http://docs.python.org/library/time.html#time.clock (http://docs.python.org/library/time.html#time.clock)

"The resolution is typically better than one microsecond."
Title: Re: An RPM-monitoring AI
Post by: Clickbeetle on October 07, 2010, 10:26:28 PM
To get a higher resolution time delta:

http://docs.python.org/library/time.html#time.clock (http://docs.python.org/library/time.html#time.clock)

"The resolution is typically better than one microsecond."


But if the issue is the 30FPS frame rate of the game (as I suspect), then a more accurate clock won't help...


But I will try this.  Maybe I'm wrong and it will work.
Title: Re: An RPM-monitoring AI
Post by: Gigafrost on October 08, 2010, 04:24:59 PM
I too agree, this code is pretty revolutionary. I can see this being used in the following ways:


I think, if possible, that this could be applied to other bot types as well.


Though I do believe that the later might not be possible atm.
Title: Re: An RPM-monitoring AI
Post by: Naryar on October 08, 2010, 04:41:50 PM
It would be cool with a self-right function, e.g. spin weapon in a restricted way when bot is upside down in order to self-right.
Title: Re: An RPM-monitoring AI
Post by: Madiaba on October 08, 2010, 11:48:29 PM
I too agree, this code is pretty revolutionary. I can see this being used in the following ways:

   
  • If bot with implemented code loses more than half of its weapons, slow down RPM in order to save battery life.
  • If bot with implemented code loses more than half of its weapons, slow down RPM in order to prevent it from spinning offbalance.
I think, if possible, that this could be applied to other bot types as well.

   
  • If flipper loses all "weapons" on its motors used for flipping, ignore trying to flip when enemy touches its smartzone and resort to trying to pin. Saving battery.
  • If popup loses the "flipping components", ignore those motors and only use the weapons. Vise versa for the "weapon components".
Though I do believe that the later might not be possible atm.
All of these are code-able, Gig.
Title: Re: An RPM-monitoring AI
Post by: Gigafrost on October 09, 2010, 02:20:26 PM
I figured so. That also reminds me, has anyone come up with an "Avoid" tactic? Like:

When a bot gets a high number of points, or when a bot has no more weapons, switch from attack to defence. Dodging engagement with the opponent.

I think it would be kind of cool to see. But it has to be possible since there is already an Engage tactic. Theoretically speaking.
Title: Re: An RPM-monitoring AI
Post by: Resetti's Replicas on December 11, 2010, 06:05:47 PM
How do I find the motor ID number?  The motor in question is a Perm-80 EL
Title: Re: An RPM-monitoring AI
Post by: Trovaner on December 11, 2010, 08:45:32 PM
The easiest way would be to use apanx bot exporter (found here (https://gametechmods.com/forums/index.php/page,page276.html))