Blender can be used to visualize results from simulations in Python.

Visualization of rigid body motion

In this example the default cube in Blender is animated. The transformation of the cube is given by a matrix received over UDP from an external Python simulation script.

Blender online visualization of a cube

The following Python simulation script simulates the Euler equations of motion for a rigid body and sends the results 10 times per second to an UDP port.

cube_simulation_online.py

import numpy
from scipy.linalg import expm
import socket
import time
import struct

M = numpy.eye(3) # Inertia matrix

def hat(v):
    return numpy.array([[0, -v[2], v[1]], [v[2], 0, -v[0]], [-v[1], v[0], 0]])

def step(delta_time, omega, R):
    R = R.dot(expm(hat(omega) * delta_time)) # Kinematic equation.
    Domega = numpy.linalg.inv(M).dot(hat(omega).dot(M).dot(omega)) # Dynamic equation
    omega = omega + Domega * delta_time
    return R, omega

R = numpy.eye(3)
T = numpy.eye(4)
omega = numpy.array([0.1, 0, 0.2]).reshape(-1,1)

delta_time = 0.1
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 

for i in range(100):
    R, omega = step(delta_time, omega, R)
    T[0:3, 0:3] = R
    data = T.flatten().tolist()
    sock.sendto(struct.pack(16 * 'd', *data), ("127.0.0.1", 5678))
    time.sleep(delta_time)
    print(T)

sock.close()

Visualization of motion using armatures

In this example a robot is animated using an armature in Blender. The armature is animated by setting the desired position of the end-effector, which is received over UDP from an external Python script.

Blender online visualization of a robot

The following Python script computes a circular motion for the robot end-effector and sends the results 10 times per second to an UDP port.

armature_simulation_online.py

import math
import socket
import time
import struct

def step(delta_time):
    return (math.cos(delta_time), math.sin(delta_time), 1.4)

delta_time = 0.1
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 

for i in range(100):
    sock.sendto(struct.pack(3 * 'd', *step(i * delta_time)), ("127.0.0.1", 5678))
    time.sleep(delta_time)

sock.close()