Ensure that the Auto Execution 'Auto Run Python Scripts' setting is enabled in the File tab of the User Preferences. This allows you to run Python scripts within Drivers.
Open a 'Text Editor' window, click 'New', and paste the following text :
import bpy
attributes = {}
def drv_calc_change(frame, attr, value):
# Used to calculate the change of a property (eg, x-coord) between one frame and the next.
# Determine whether we already have a value for this attribute
if attr in attributes:
attribute = attributes[attr]
else:
# Not found - create a new record for it and store it
attribute = {'frame':frame, 'value':value}
attributes[attr] = attribute
# Calculate the difference
difference = value - attribute['value']
# If new frame then store the new value to use next time.
if frame != attribute['frame']:
attribute['frame'] = frame
attribute['value'] = value
attributes[attr] = attribute
return difference
if 'drv_calc_change' in bpy.app.driver_namespace:
del bpy.app.driver_namespace['drv_calc_change']
bpy.app.driver_namespace['drv_calc_change'] = drv_calc_change
Give it a suitable name and click 'Run Script' to run it now and tick 'Register' so that it is automatically run each time the .blend is opened.
Running the script will register a new function that is available from within Drivers that will calculate the change in any attribute between different animated frames. The script works by storing a list of attributes along with the value for that attribute and the associated frame number, returning the difference between the value passed into the function and that stored from the previous frame. On change of frame the new value is stored to be used for the next frame. Since each is stored along with the attribute name, the same function can be used for any number of properties simply be assigning each a different name.
Go to the object you want to track the velocity of. Open its 'Object' properties and in Custom Properties 'Add' a new property. Edit it and set its name to 'dx' (Delta-X), Value to '0.0', Min to -999999, Max to 999999, click 'OK' to accept. Right-click the value field and 'Add Driver'.
Go to the Graph Editor and change mode to 'Drivers'. Select the new 'dx' driver, open the properties panel (press 'N' while the mouse is in the Graph Editor). Ensure the default 'var' Variable is set to Transform Channel, the Object/Bone property is set to the object you want to track, Type is set to 'X Location' and Space is 'World Space'.
Move up to the Drivers panel and set Type to Scripted Expression and set the expression to 'drv_calc_change(frame, "dx", var)'. This will set the value of the Property to that returned from the new function.
Repeat the above for 'dy' and 'dz' - using the appropriate Transform Channel (Y, Z) for each and using the appropriate label ("dy", "dz") in place of "dx" in the expression .
The 'dx', 'dy' and 'dz' Custom Properties should now automatically update with the velocity in each axis when moving between different frames of the animation.
Set some keyframes to move the object around and step through the animation to check that the properties are automatically updated to the velocity at each frame.
In the same way we can now calculate the change in Velocity to arrive at the Acceleration. To do this, repeat the same steps to create three new Custom Properties - named 'ddx', 'ddy', 'ddz' - but this time based on the new 'dx', 'dy', 'dz' properties instead of the object X, Y, Z channels. This can be achieved by using the Variable Type of 'Single Property', setting the 'Object' to the object being tracked and the Path to '["dx"]' for 'ddx', '["dy"]' for 'ddy'', and '["dz"]' for 'ddz'.
You should now have Custom Properties on the object for velocity (dx, dy, dz) and acceleration (ddx, ddy, ddz) and these should update automatically each time the 'frame' is changed. You can use these properties in drivers by way of the 'Single Property' variable type in the same way as already described above.
The acceleration could be used to automatically position a target for a Damped Track constraint to mimic the tilting of a Helicopter/Quadcopter to achieve the desired tilting to follow a path - rather than having to keyframe the motion by hand - as demonstrated :
NOTE : The function does not allow for jumping to specific frames in the animation or running the animation backwards - only on change of frame. You should Bake the animation to keyframes prior to rendering to ensure that the calculated values are fixed prior to rendering - otherwise strange effects can occur such as sub-frames causing the acceleration to be mis-calculated (as the frame doesn't step by '1') or the 'initial' state being different between rendering runs.
Sample .blend file attached.
f((x+h) - f(x-h)) / 2h
first derivative approx. Iterate over frame range using the object'sob.matrix_world.to_transform()
which "should" give a reasonable result regardless of animation type (keyframes, constraints, drivers etc). From blenderartists.org/forum/… $\endgroup$