Relation between BGE framerate and Action framerate

By BGE framerate I mean the rate at which True pulse is fired (and thus attached Python controller script is executed) and by Action framerate I mean the rate at which the value returned by KX_GameObject.getActionFrame() is changing. (I've heard the term Logic framerate in the context of BGE, but I'm not sure if it is the same thing as BGE framerate I'm talking about :-/ Sorry!)

Here is a small snippet which I used for testing (which should clarify what I mean by BGE frame and Action frame):

import bge

BGE_frame = 0

def main(cont):
global BGE_frame

arm = cont.owner
if not arm.isPlayingAction():
arm.playAction("run", 0, 45, play_mode=bge.logic.KX_ACTION_MODE_PLAY)

print(BGE_frame)
print(arm.getActionFrame())

BGE_frame += 1


Using the above script for Python controller attached to an Always True sensor gives following result (the n-th BGE frame and corresponding Action frame):

http://pastebin.com/NK2RrVkR

As we can see, there is a significant difference in both frame-rates (e.g. the 11th BGE frame corresponds to the 4th Action frame and 16th BGE frame corresponds to the 6th Action frame -- so roughly 5 BGE frames corresponds to 2 Action frames).

Assuming that the action starts playing when BGE frame is 0, in what way can we compute the Action frame from the BGE frame and vice-versa? More precisely, I'm looking something like:

import bge

BGE_frame = 0

def main(cont):
global BGE_frame

print(BGE_frame)
print(BGE_frame_to_Animation_frame(BGE_frame)) # TODO: Outputs same result as above

BGE_frame += 1


Thanks!

I think I solved it as follows:

import bpy, bge

BGE_frame = 0

scene = bge.logic.getCurrentScene()
bpy_scene = bpy.data.scenes[scene.name]

BPY_FPS = bpy_scene.render.fps / bpy_scene.render.fps_base
BGE_FPS = bge.logic.getLogicTicRate()

BPY_BGE_RATIO = BPY_FPS / BGE_FPS

def BGE_frame_to_Animation_frame(BGE_frame):
return BGE_frame * BPY_BGE_RATIO

def main(cont):
global BGE_frame

arm = cont.owner

print(BGE_frame)
print(arm.getActionFrame()) # Kept for comparison
print(BGE_frame_to_Animation_frame(BGE_frame)) # Outputs approx. same result as above

if not arm.isPlayingAction():
arm.playAction("run", 0, 45, play_mode=bge.logic.KX_ACTION_MODE_PLAY)
BGE_frame = 0
else:
BGE_frame += 1

print("\n")


I'm not sure of it is a good practice to access blender data from BGE, but it works :-) Comments/suggestions are welcome! Thanks.