I’ve been playing around with the idea of building a rig to suspend an object, like a camera or prop, using three wires and then control its position in 3-D space using a few stepper motors and a micro-controller. The general idea is similar to the skycam system they use at football games and other pro sports, or a large scale delta robot. The first thing I needed to figure out was how much I wanted this rig to be able to hold and how much tension (force) would be required to hold and move this weight around. Additional I wanted to be able to visualize the results so I could look for any peaks, valleys or other anomalies that would throw off my calculations. I ended up writing the python script below utilizing the mpmath, sympy and matplotlib libraries to calculate the tension on a wire due to a suspend mass at a specific height and plot it as the weight moves around the x/y plane. The image below is a sample of the output from this script for a 5 kg mass suspend 2.0 m above the ground with three anchor points at 3.0 m above ground level and each 120 degrees apart.
from mpmath import * from sympy import * # Gravity constant g = 9.81 # Length function def length(m): s = 0.0 for n in range(len(m)): s += m[n]**2 return sqrt(s) # Tension Function def tension(x, y, z): # Location of object loc = Matrix([[x, y, z]]) # Calculate x, y, z length of each wire la = pta - loc lb = ptb - loc lc = ptc - loc # Calculate the tension ratio of each wire ra = la / length(la) rb = lb / length(lb) rc = lc / length(lc) # Put ratios into matrix form a = Matrix([ra, rb, rc]) # Calculate solution sol = lu_solve(a.T, f) # Check if results are valid for n in range(len(sol)): if (sol[n] < 0): sol[:] = 'nan' # Return tension for wire 'a' return sol[0] # Locations of anchors points [[ x, y, z]] pta = Matrix([[ 0.00, 2.00, 3.0]]) ptb = Matrix([[-1.73, -1.00, 3.0]]) ptc = Matrix([[ 1.73, -1.00, 3.0]]) # Enter the mass of the object suspended mass = input("Enter mass of object (Kg): ") # Enter height of object z = input("Enter height of object (m): ") # Force due to gravity on object [x, y, z] f = Matrix([0.0, 0.0, mass * g]) # Create a symbolic function to return tension at position force = lambda x, y: tension(x, y, z) # Plot tension on wire over area of anchor points splot(force, [-1.73, 1.73], [-1.0, 2.0])
Change Log:
1/4/2014: Added check to tension function to filter out invalid results. This makes the edges of the plot a little rough but gives a better visual.