How to get the speed of a Camera with Python? I'm currently working on a project in 2.79b containing multiple shots that require several cameras (2+ keyframes for Location with a Linear Extrapolation applied to them) to be moving at the same speed.

At the moment, my workflow involves placing 2 keyframes for the active camera's Location and essentially estimating how far apart they should be spaced in order for the speeds to match.

I am looking to create a Python Script that logs the speed of cameras in the scene (in Blender Units per second (U/s)?), on each frame, and outputs it to the console, for example. I'd also like it to output this value every time a keyframe on the current camera is changed, preferably in real-time.

Here's a (very rough!) example of what I'm hoping to achieve in terms of output...



What would be the most practical method of scripting this? Would it be best to find the distance travelled by the camera, for example, between the current and previous frame (e.g. through the difference in location), and then perform a "Speed = Distance/Time" calculation to obtain the speed, or is there a function in the Python API that provides access to this data automatically?

Any help would be much appreciated, thanks!
On every sceneupdate we can call a function which checks for fcurves and then evaluate the current and previous frame.

The script creates a panel in the camera data section and displays the speed there.



import bpy

class CameraSpeedPanel(bpy.types.Panel):
    """Creates a Panel in the Data properties window
        when a camera is selected"""
    bl_label = "Camera Speed"
    bl_idname = "CAMERA_PT_speedometer"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "data"

    def draw(self, context):
        layout = self.layout

        cameras = [ob for ob in context.scene.objects if ob.type == 'CAMERA']

        for cam in cameras:
            print(cam.name)
            row = layout.row()
            lbl = cam.name
            if context.scene.camera == cam:
                lbl += ' (active)'
            if cam == context.scene.objects.active:
                row.label(lbl, icon = 'OUTLINER_OB_CAMERA')
            else:
                row.label(lbl, icon = 'CAMERA_DATA')
            row.label(self.getSpeed(context.scene, cam))

    def getSpeed(self, scene, ob):
        if (ob.animation_data == None or
            ob.animation_data.action == None):
            return '(not animated)'
        current = ob.location.copy()
        previous = ob.location.copy()
        frame = scene.frame_current
        for i in range(3):
            crv = ob.animation_data.action.fcurves.find('location', i)
            if (crv != None):
                current[i] = crv.evaluate(frame)
                previous[i] = crv.evaluate(frame - 1)
        output = str((current - previous).length)
        output = (output[:10] + '..') if len(output) &gt; 12 else output
        print(output)
        return output


def register():
    bpy.utils.register_class(CameraSpeedPanel)


def unregister():
    bpy.utils.unregister_class(CameraSpeedPanel)


if __name__ == "__main__":
    register()