2
$\begingroup$

This is the deal now...I have a speed data in a .DAT file; For example lets say the file looks like this

0.111
1.11
2.22
3.33
4.555
1.111
2.22
10.11

What this data represents is the instantaneous speed in m/s of a certain object, these data intervals are in 10 mil-second difference that means that we get the speed of the object in every 10 mil-second interval. So I was wondering on how I will convert this to a motion on an empty in blender using python. Any help or ideas in the comment is also more than welcome.

$\endgroup$

1 Answer 1

4
+50
$\begingroup$

Integrate the velocity curve.

Please note: Am currently working on an addon that uses 3rd party addons scipy (to integrate here) and matplotlib to plot.

Displacement is the integration of the velocity curve.

Instead of 10ms between points (would need frame rate of 100fps for a frame each) have spread the velocity across the scene frame range. dt is how many frames between points.

Scipy.integrate.cumtrapz is used to integrate the velocity list, setting initial displacement to zero. This is basically the sum of the area of each trapezium. Remember have bloated out the time scale, for strictly having 10ms between readings

t = np.linspace(0, len(v) * 10 / 1000, len(v))
s = integrate.cumtrapz(v, t, initial=0)

and the frame for 10ms (where fps = 24) can use the utility method.

>>> bpy.utils.time_to_frame(10 / 1000)
0.24 

Result of Matplotlib.pyplot

enter image description here Displacement in blue, velocity (scaled by frames per point (dt)) in red

The resulting fcurve.

enter image description here

Test script maps the displacement to the frame range, considering velocity as blend units per frame, rather than meters per second.

import bpy
import numpy as np
from scipy import integrate

plot = False


context = bpy.context
scene = context.scene
ob = context.object
ob.animation_data_create()
ad = ob.animation_data
action = ad.action or bpy.data.actions.new("Displacement")
ad.action = action

v = np.array(
    (
        0.111,
        1.11,
        2.22,
        3.33,
        4.555,
        1.111,
        2.22,
        10.11,
    )
)

t = np.linspace(
    scene.frame_start,
    scene.frame_end,
    len(v))
dt = t[1] - t[0]
s = integrate.cumtrapz(v, t, initial=0)
if plot:
    from matplotlib import pyplot as plt
    plt.plot(t, s)
    plt.plot(t, dt * v)
    plt.savefig("disp.png")
    plt.show()
# ravelled list of frame, value keyframes
kfs = np.empty((v.size + t.size,), dtype=t.dtype)
kfs[0::2] = t
kfs[1::2] = s
# move in x location
fc = action.fcurves.find("location")
# remove if exists
if fc:
    action.fcurves.remove(fc)
fc = action.fcurves.new("location", index=0)
fc.keyframe_points.add(len(v))   
fc.keyframe_points.foreach_set("co", kfs)
# add linear velocity points before and after
kfs = np.insert(kfs, 0, (-dt, -v[0]))
kfs = np.append(kfs, (scene.frame_end + dt, s[-1] + v[-1]))
# set handles based on before / after
fc.keyframe_points.foreach_set("handle_left", kfs[:-2])
fc.keyframe_points.foreach_set("handle_right", kfs[2:])
$\endgroup$
1
  • $\begingroup$ Exemplary. Thank heavens I didn't have a shot at this one! $\endgroup$
    – Robin Betts
    Feb 27, 2020 at 10:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .