Computing the cable tensions from the sag surveys.

oct 2020
Intro:
general steps to compute tension
Details of how it was done
Where the code is located

Intro

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 cable.
• 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 cable slope.
• cableTension=b * cableWeight/linearDistance  * cos(cableZAngle)
• 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 ghisbain)
• i switched over to using the catenary fit and the actual cable length.
• 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 drawings.
• This works since the platform side of the cable was usually the one blocked by the  platform or other cables.
• 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 cables scanned.
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 computer
• 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 software.

Idl routines have been written to input the .las files and compute the tensions. The major processing steps are:

• 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 cable points.
• 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 this line
• 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 indices)
• 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 x,z plane
• 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.

• fitcatenary3dlm(p3,p3cblIar,index,fitI,fitcat)
• 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 parameter :).
• 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:
• b=1/p2
• 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  * cos(cableAngle)
• the cableAngle is computed from the catenary fit and the max,min x values (more info)
• The tension was computed in Newtons (since i used meters for distance in the p50) and then it was converted to lbs of force.
• the routine cmpcbltension() does this.
• The cable tension error is linearly related to the error in the cable linear density. The values used were:
•  cable  diameter (inches) linearDensity lbs/foot locations for cable 3" 18.9 platform mains catwalk to T4 3 1/4" 22.18 platform aux backstay mains catwalk to T8 3 5/8" 27.60 backstay aux 1 7/8" 7.39 catwalk to t12?

Where the code is located

• /share/megs/phil/x101/p50/pro has:
• cmpcbltension.pro,findcables.pro,fitcatenary3dlm.pro,getxyzpnts.pro,pntlinedist2.pro, and preproccable.pro.
• cbl.h (defines lots of the structures used.
• /share/megs/phi/x101/p50/cables
• proccableall.pro .. this is a template that is located for each measurement location (eg t4 min,t8main, t12backstays..etc)
• /share/megs/phil/x101/p50/2008xx,2009xx/   has the code for each location (by measurement date).
home_~phil