Computing the cable tensions from the sag surveys.
general steps to compute tension
Details of how it was done
Where the code is located
Each telescope cable hangs between two
connection points in a catenary curve. The sag of
the cable comes from the cable weight and gravity.
As the tension in the cable increases, the sag gets smaller.
By fitting a catenary to the cable curve we can compute the tension
in the cable.
The general steps to compute
the tension from the sag surveys
- collect the p50 data
- exclude extraneous points (so you can manipulate the data).
- for the aug2020 surveys there were 14 to 255 million
3d points per data set. To exclude points:
- window in the xy, xz, or yz plane. This projection is easy
since you just ignore the other 3d coordinate.
- select 2 points from a cable or set of cables and
use it to generate a line (in 2d or 3d space)
- Compute the perpendicular distance from each point to this
line (dot product and then Pythagorean theorem).
- Use this distance to exclude points
- These things can typically reduce the points from
10's of million to a few 100 thousand.
- move 3d to 2d
- project the 3d points onto the xy place
- select 2 points on the cables to generate a line
- Use the fit coef to rotate the xy line to the x axis. This
leaves you with data points clustered around the x,z plane.
- select points for each cable
- after rotating the 3d points to the xz plane, plot the 3d
data in the y,z plane
- This will separate the cables by their y distance.
- select 2 points on each cable, define a line, and compute
the distance from all points to each line
- let the user iterate on the clipping distance.
- These points will be the starting point for fits to each
- fit a catenary to the set of points for each cable.
- In the xz plane first fit a parabola to each cable set:
- zp=p0 + p1*x + p2*x^2
- Use the parabola coefs to compute the starting values for
the catenary fit:
- zc= a + b*(cosh(x-c)/b -1)
- Use a Leven -marquardt non linear least squares fit
to fit for the catenary coef a,b,c
- compute the tension from the catenary parameters and the
- cableTension=b * cableWeight/linearDistance *
- The cableZ angle was initially taken from the linear
coef of the xz parabolic fit.
- this gave xz cable angles that differed by up to a degree
for the same set of main cables (pointed out by pierre
- i switched over to using the catenary fit and the actual
- For xmax use the x value for the maxium z value (this is
at the tower)
- compute xmin=xmax -cable length (taking this from the
- This works since the platform side of the cable was
usually the one blocked by the platform or other
- Evaluate the catenary fit at xmax,xmin, get the
slope and then the xz angle of the cable.
- projecting tensions to balance forces on platform and
measure imbalances on the towers.
- The catenary fits is used to compute the xz vertical angle
- The linear fits in the x,y plane give the rotation angle to
move the cables to the x,z plane
- The angles are biased by the y axis of the p50 scanner
- the difference in the angles tells the relative angle
between the main and aux main cables.
Details of how the tension was computed
Collecting the data
The leica p50 laser scanner is used to
collect the data. It scans an area that includes the cables. We
typically collect between 5 and 90 million points for each set of
After the collecting the data some leica software is get the 3d
points into a .las file that can be read by the
processing programs. These leica programs run on windows.
- leica xxx will move the project from the p50 to the windows
- cyclone can then be used to input the data files, plot the
data, and then output the data as .las files.
- the .las files are then moved to Linux computers.
Idl routines have been written to input the
.las files and compute the tensions. The major processing steps
- Exclude points far from cables
- this can remove a large number of points
- select points that belong to each cable
- since the cables should hang vertically we can rotate the
points to lie close to the xz plane
- Points are excluded by defining lines (via 2 points) and
then computing the distance from all points for each line
- The final exclusion is by fitting a parabola to each set of
- fit a catenary to the points.
Inputting the data
- getxyzpnts() will input the data
- plcdinplas() will input the .las file
- an xyz[3,n] is then generated by scaling the .las
input data to floating point
Localizing the cables:
Most of this code is trying to exclude points
that don't belong to the cable. findcables() tries to select
points around the cables and reducing the # of points to a
manageable number (typically going from 64e6 to around 2e5 points.
preproccable() then does a more in depth attempt at selecting the
points for each cable.
- findcables(xyz, p3, p3cbIar) will exclude most points
that don't belong to a cable
- input xyz[3,n)
- output: p3[3,m] and p3cblIAr[ncables]
- plot all points in the x,z plane. let the user exclude
points using x and z ranges.
- user selects 2 points in the x,z plane that lies along
the middle of the cables.
- generate a line and compute the distance from all points to
- plot the distance from all points to this line. let the user
exclude points by this distance.
- set p3[3,*] to the included points
- do a robust linear fit to p3 points in the x,y plane.
- copy p3 to a rvec[3,m] (a temp variable)
- rotate the rvec variable by the x,y slope (after removing
the y offset)
- force the x,z slope to be positive.
- this should put the cables close to the x,z plane, only
separated by their y offsets
- plot the rotated points y vs z. this will spread
the cables out because of their y differences
- let the user select 2 points along each of the cables,
generate a line for each cable
- loop through each cable
- plot the distance of all points to the line for this cable
- let the user specify the maximum distance to keep
- use this to select indices in p3[3,M] for this cable.
store the indices in p3CblI[icable].pind (ptr to array of
- return p3[*,m] and p3CblIar[ncables] holding the indices
into p3 for each cable.
- preproccable(p3, p3cblIAr,index,fitI) This is called
for each cable found in findcables
- refit the points for the cable
- x,y linear
- y,z, x,z 2nd order
- compute the distance of all points from each fit and let the
user exclude points
- rotate the points to the x,z plane
- fit a parabola to this and plot the residuals vs x,y, and
z.. let the user exclude points
- When done refit the points in the x,y plane
- For each cable we end up with
- indices into p3[3,m] for this cable
- the x,y rotation angle needed to move this cable to the
- the x,z angle giving the vertical slope of each cable
- the parabolic fit parameters that can be used to generate
the initial values for the catenary fit.
Fitting a catenary and computing the tension.
- this uses a Leven -Marquardt non linear least squares fit a
catenary to the data points.
- I ended up having to compute the derivatives for each
- zc= a + b*(cosh(x-c)/b -1 ) is a catenary.
- a parabola is a close approximation to a catenary.
- computing the initial values from the parabolic fit
- zp=p0 + p1*x + p2*x^2 is a parabolic fit
- for the catenary let u=(x-c)/b . since the cosh is
exponential , u must be small and we can do a taylor series
expansion in u.
- cosh(u)= 1 + u^2/2! + ...
- replacing u with (x-c)/b and expanding gives
- zc=a + b*((1+(x-c)/b)^2/2 -1) = (1/b)*x^2 +
(-2c/b)*x + (a +c^2/b)
- equating each term with the parabola's coef gives:
- c=-(b*p1)/2 = -p1/(2*p2)
- a=(p0 -c^2/b)=p0 - (p1^2/(4*p2)
- These are used for the initial values of the fit
- Computing the tension.
- The cable tension is b * cableWeight/linearDistance *
- the cableAngle is computed from the catenary fit and the
max,min x values (more
- The tension was computed in Newtons (since i used meters
for distance in the p50) and then it was converted to lbs of
- the routine cmpcbltension() does this.
- The cable tension error is linearly related to the error
in the cable linear density. The values used were:
catwalk to T4
catwalk to T8
||catwalk to t12?
Where the code is located
- /share/megs/phil/x101/p50/pro has:
- cbl.h (defines lots of the structures used.
- proccableall.pro .. this is a template that is located for
each measurement location (eg t4 min,t8main,
- /share/megs/phil/x101/p50/2008xx,2009xx/ has the
code for each location (by measurement date).