I am using blender to model a robot in my own robot simulator. To create better videos of my simulation results, I would like to log e.g. the positions and orientations of all segments to a log file and import that into blender to create an animation. Is there a canonical way to write such log files, or is there even a python module already out there?
Asked
Active
Viewed 2,064 times
1 Answers
4
There are several easy ways to exchange data, common formats are .csv or .json and both can be written and read easily.
What you might end up doing is have csv file like this:
timestamp,p1x,p1y,p1z,p2x,p2y,p2z,p3x,p3y,p3z....etc
0:000,x,y,z,x,y,z,x,y,z....
0:020,x,y,z,x,y,z,x,y,z....
0:030,x,y,z,x,y,z,x,y,z....
The timestamp could be as fine grained as you want, or 24 frames per second. Exactly how you turn the information into an animation is entirely up to you and can also be entirely scripted.
Here's a movement.csv, which uses a frame number instead of the timestamp, simply because it makes the example more convenient.
To start off you might want to simply key-frame some empties. Let's say we have 48 lines of data for 3 points in space, and they describe these arcs (though can be any complex path)

import csv
import os
import bpy
# add 3 empties programatically to be certain it works as a demo
mt1 = bpy.data.objects.new('mt1', None)
mt2 = bpy.data.objects.new('mt2', None)
mt3 = bpy.data.objects.new('mt3', None)
empties = [mt1, mt2, mt3]
for m in empties:
bpy.context.scene.objects.link(m)
filename = 'movement.csv'
directory = '/home/zeffii/Desktop' # <-- if you have linux or osx
# directory = r'c:\some\directory' # <-- if windows, the r is important
# directory = 'c:/some/directory' # <-- if windows (alternative)
fullpath = os.path.join(directory, filename)
with open(fullpath, 'r', newline='') as csvfile:
ofile = csv.reader(csvfile, delimiter=',')
next(ofile) # <-- skip the x,y,z header
for line in ofile:
f, *pts = line
# these things are still strings (that's how they get stored in the file)
# here we recast them to integer and floats
frame_num = int(f)
fpts = [float(p) for p in pts]
coordinates = [fpts[0:3], fpts[3:6], fpts[6:9]]
bpy.context.scene.frame_set(frame_num)
for ob, position in zip(empties, coordinates):
ob.location = position
ob.keyframe_insert(data_path="location", index=-1)

zeffii
- 39,634
- 9
- 103
- 186