Opened 3 years ago

Last modified 31 hours ago

#124 assigned enhancement

It should be possible to fix x,y separately from z — at Version 3

Reported by: Tarquin Wilton-Jones Owned by: Olly Betts
Priority: minor Milestone: 1.4.16
Component: cavern Version:
Keywords: Cc:

Description (last modified by Olly Betts)

With some surveys, it might only be possible to fix the horizontal x,y coordinates accurately at a different location from the z height. An example would be a trig point for x,y, and a benchmark for the z (this is my actual use-case), which could be in completely different locations in the surface survey. Another would be for a marine cave where the z can be fixed at the water surface, while the x,y might be taken from local mapping at an obvious landmark. In the UK, it is common for benchmarks to have very imprecise locations but highly accurate heights, and trigpoints often do not have a benchmark.

Currently, the *fix command insists on having x,y and z coordinates for every fix. It would be useful for the *fix command to support - as a measure like this:

*fix trig 1234 5678 -
*fix benchmark - - 317

The present workaround is quite laborious:

  1. Fix the location of the benchmark with random x,y and actual z.
  2. Process the survey and read the z of the trigpoint.
  3. Remove the benchmark fix.
  4. Add a fix for the trigpoint, using the calculated z, and the actual x,y.
  5. Hope that loop closure never changes the height difference between the points.
  6. Add a load of comments to explain why the benchmark has no height fix, but the non-benchmark does.

Or: Specify approximate heights or x,y for the unknown quantity at each of the two points, using standard deviations to enable the bad coordinates to be ignored.

Change History (3)

comment:1 Changed 3 years ago by Olly Betts

Essentially the same question was also asked on the cave-surveying list. As I replied there:

It should be possible to allow height-only or no-height fixes (or legs which only connect horizontally or only connect vertically) with the current loop closure code, but I think it would be a lot of work.

I'll leave this open though.

Maybe at some point we'll redo the loop closure code. The tight memory usage of the current code is much less important than it was in the 1990s, and it'd be handy to be able to iterate quickly to solve a slightly modified network for interactive changes to the network while trying to locate blunders (break a leg, quickly see how that affects station positions).

comment:2 Changed 9 months ago by Olly Betts

Component: Othercavern

comment:3 Changed 5 months ago by Olly Betts

Description: modified (diff)

I had another look at this.

I'm not sure if the network simplification would easily handle these cases, but we probably have it leave such legs alone without too much work. Such legs should be rare.

I think legs that only connect horizontally or only vertically are probably feasible (this is the "infinite variance" case). We'd need to:

  • check connectivity for horizontally and vertically separately (if this feature is used)
  • when identifying connected components and articulation points, we treat any connection as a connection
  • when building the matrix, we skip unconnected directions for a leg (and covariances involving those directions, but they ought to be set to zero anyway)

Handling cases of zero variance (i.e. fixing or equating) looks harder. Fixed points don't have a row/column in the matrix; equated stations share a row/column with all the stations they are equated to.

Each row/column has 3 sub-rows/sub-columns (for x, y, z) so it seems we'd need to omit the affected sub-rows, but that makes indexing into the matrix as we build it much more complicated. The matrix is symmetric and we only store half of it. Perhaps the indexing is doable if we have all the 3 sub-row rows first, then the 2 sub-row rows, then the 1 sub-row rows. We might need to pre-calculate the offset for the start of each row, or something like that.

Having the sub-rows there but unused would make the matrix solution more complicated.

Building the matrix with unused rows and then stripping them out before solving also seems complicated.

We also need some extra handling to deal with copy the station coordinates from the solved matrix to the stations as it's no longer as simple as copying adjacent sub-rows to the shared pos structure which equated stations already point at.

Or as an very different approach, maybe we can set up the values in sub-rows/sub-columns we want to omit such that the matrix solution forces them to be equal. For a simple 2x2 matrix it's possible:

(1 -1) (x) = (0) <- "unused" sub-row
(0  1) (y) = (a)

 ^"unused" sub-column

This implies x - y = 0 and y = a i.e. x = y = a

Maybe this doesn't work in the full situation though.

Note: See TracTickets for help on using tickets.