Help for MARSITILT
PURPOSE:
MARSITILT computes the tilt an instrument would have if placed at
the given point. The minimum and maximum tilts are provided, as well as a
status band, and the program accounts for clock angle rotation and sinkage.
It will also compute the delta-tilt between the SEIS and WTS instruments
for InSight.
The input for MARSITILT is an XYZ image such as that created by MARSXYZ.
This can be a single 3-band file (preferred) or three 1-band files.
The output of MARSITILT is a 3-band file of type REAL. The first band is
a status (flag) band indicating whether or not the result is within limits.
The second and third bands are the minimum and maximum tilts, respectively.
MARSITILT additionally outputs instrument-specific surface normal and Z value
files, which are needed by MARSIROUGH.
EXECUTION:
marsitilt inp=data.xyz out=data.tfs uix_out=data.uis zix_out=data.zis -seis
marsitilt inp=data.xyz out=data.tfw uix_out=data.uiw zix_out=data.ziw -wts
marsitilt inp=data.xyz out=data.tfh uix_out=data.uih zix_out=data.zih -hp3
marsitilt inp=data.xyz out=data.tfh uix_out=data.uih zix_out=data.zih -heli
marsitilt inp=data.xyz out=data.tds -seis -delta
METHOD:
At each pixel in the output file, MARSITILT attempts to "place" the given
instrument at that point. The point represents the grapple on the instrument,
so the XY position of the point is what would be communicated to the IDS
team to actually place the instrument there on the surface. The XY position
is derived from the XYZ input file for the given pixel. If there is no XYZ
position for the pixel, the pixel is skipped.
Note that the program works internally in Site frame. This aligns all the tilts
with the gravity vector, giving true tilt relative to gravity. It will convert
the given XYZ to this frame automatically. While other frames could be used
(e.g. -rover for Lander frame), the tilts would then be measured relative to the
lander, which is generally not what it desired.
Instrument Feet
---------------
The size and spacing of the feet for each instrument is given in the
marsi_instruments class that is compiled into the program. This should
be read from a config file, but time constraints may prevent this from
happening.
The program represents the feet as a set of circles - 3 each for SEIS and WTS,
4 for HP3 and HELI. The size of these circles matches the size of the feet as
they interact with the ground. Although one should consult the class file for
specific values, at the time this help was written, the circle radii are 3cm
for SEIS, 4.2665cm for WTS, and 5cm for HP3.
Note that the size of the M20 Helicopter foot is expanded to cover the
possible leg splay. It is this wider than it should be. This however causes
no issues as the helicopter use case is to always clock the entire circle, so
the width of the foot really doesn't matter.
The Z location of the foot is defined as the highest point within the foot
patch, the idea being that the foot will "perch" on the highest point available.
However, this is sucseptible to noise spikes in the data. Therefore, a
statistical analysis (mean and standard deviation, or sigma) of the Z points
within the foot patch is done, and all points exceeding some number of sigma
away from the mean are excluded from the analysis. The threshold is determined
by the FILTER_SCALE parameter, which is then multiplied by sigma.
Tether Effects
--------------
The feet are initially set assuming the tether points directly down the
-X axis. However, the actual instruments while being deployed will tend to
rotate so the tether points back toward the spacecraft. This is accounted
for by rotating the instrument (i.e. feet position) based on the tether pivot
points.
For SEIS, the tether emanates from a single tether box position. This
position is hardcoded at x=0.145, y=-0.101 in the lander frame. The tether
points radially from this point to the instrument deployment location, and
the SEIS feet are rotated to match.
For HP3, the algorithm is more complicated, because the tether can be routed
different ways based on where the instrument is being deployed. The algorithm
comes from Won Kin in Section 347:
HP3 has two "virtual" tether anchor points.
- HP3 tether guard post1 --- P1 = (X1, Y1) = (0.083, -0.435)
- HP3 mount --- P2 = (X2, Y2) = (-1.279, 0.149)
- Line equation between two anchor points:
y = ((Y2-Y1)/(X2-X1)) * (x - X1) + Y1 = mx + b
- Given the current tether position (X0, Y0):
- If Y0 > m * X0 + b, use HP3 tether guard post1 P1 as the "virtual" anchor
point.
- Otherwise, use HP3 mount P2 as the "virtual" anchor point.
You can determine the tether direction by assuming that the tether passes
through the "virtual" anchor point.
For WTS, there is no tether. However, the arm moves slowly enough that the
WTS is likely to rotate with the arm, meaning that there is a most-likely
rotation value that acts as if there was a tether.
Additionally, there are radial and cross-radial offsets between the WTS and
SEIS, because the grapples are not coaxial in the nominal placement. The WTS
position is thus offset by an amount determined in the WTS_OFF parameter. These
offsets are applied after WTS rotations (instrument clocking and rotation due to
tether) are done. All WTS rotations (such as for clocking) are done centered
around the nominal(SEIS) location. This means that WTS clocking rotation
(see below) also introduces a small translation in the WTS.
The M20 helicopter obviously has no tether.
Instrument Clocking
-------------------
Although the tether controls the rotation of the instrument while hanging on
the arm to some extent, the instrument can still rotate within a certain range.
This rotation is called "clocking".
Zero clocking is defined as the rotation resulting from the tether calculation.
The program analyzes the tilt throughout this range of clocking angles.
Because it is computationally intractable to compute every possible angle,
we settle for checking a discrete set of clock angles. The set of angles
checked are controlled by the CLOCK_RANGE and CLOCK_STEP parameters. Generally
these should be set to be centered around 0 clock angle (and to include 0
clock angle), but this is not mandatory.
Settling of Feet
----------------
The Z location of each foot is defined as the highest point found within the
foot circle (after removing outliers) - the theory being, the foot will be
perched on the highest point in the area. However, if the ground is sandy,
the feet are likely to "settle" into the sand by some amount. For this reason,
the feet are "settled" by an amount specified by the SINKAGE parameter. This
amount is added to each foot location (because +Z is down, adding the value
lowers the foot location). Tilt analysis is then done using all combinations
of settled and unsettled feet. This should pick up the worst-case scenario on
both ends of the spectrum - no settling and maximum settling.
Tilt Computation
----------------
For SEIS and WTS, tilt is computed by taking the Z value of each foot,
constructing vectors between them, and using the cross-product to determine
the normal of the plane defined by those points. As noted above, this is done
for each combination of settled and unsettled feet, and the min and max tilts
across all combinations are gathered.
HP3 and Heli have 4 feet. The 4 foot points are unlikely to lie in a single
plane; it it possible for the instrument to sit unstably on any set of 3 feet.
For that reason, the above computation is performed for all combinations of 3
of the 4 feet. Thus the best (min) and worst (max) cases are determined no
matter which feet are actually stably on the ground. This means that each
combination of 3 feet is also analyzed for each combination of settled and
unsettled feet. In reality, the compliance of the ground is likely to allow
all 4 feet to sit on the ground (and for the M20 helicopter, the compliance
of the legs), but this algorithm ensures we look at the worst case.
The min and max tilts are computed as above for each clock value, and then
the minimum and maximum across all clocks are computed to determine the final
output value.
Delta-Tilt Computation
----------------------
The delta-tilt is a comparison between the tilt of the SEIS and the tilt
of the WTS that covers it. It is computed by first computing tilt as above
for the SEIS. At each SEIS clock point, the tilt of the WTS is computed.
This also follows the above tilt algorithm, except the parameters
DELTA_WTS_RANGE and DELTA_WTS_TILT are used to determine the clock range.
At each combination of SEIS and WTS tilts, the delta tilt is computed, as
the arccos of the dot product between the two normal vectors. The min and
max delta tilt is then computed across all combinations of clocks for both
instruments.
It is important to note that this is not finding the min/max tilt of each
instrument and then computing the angle between them. It is computing the
angle between each and every combination of clock angles (subject to the
step size and range parameters), and determining the min/max of those.
Delta-tilt is available for InSight only.
Output File Format and State Band
---------------------------------
The output file consists of 3 bands in floating-point format:
Band 1: State band (contains goodness flag)
Band 2: Minimum tilt or delta tilt
Band 3: Maximum tilt or delta tilt
The min/max tilt/delta-tilt are expressed in degrees.
The State band can contain the following values:
0 = no value
1 = n/a
2 = n/a
3 = exceeds tilt threshold
4 = n/a
5 = tilt within limits (good)
As with all the instrument placement products, 5 indicates everything is within
limits, with other values indicating what parameter is out of limits.
Output Instrument Surface Normal, Z, and XYZ
--------------------------------------------
There are four optional output files, UIX_OUT, ZIX_OUT, UPX_OUT, and XPX_OUT.
UIX_OUT and ZIX_OUT files contain intermediate results that are intended to be
supplied as inputs to the MARSIROUGH program. UPX_OUT and XPX_OUT files are
similar to UIX_OUT and ZIX_OUT except that they are in general measured in
Lander frame instead of Site frame. Also, XPX_OUT contains all XYZ coordinates
instead of just the Z band.
The UIX_OUT file is a 3-band float unit-vector normal file in the same format
as produced by the MARSUVW program. However, the normal is calculated in a
special way. It is the normal not of the surface, but of the instrument
itself, when located at the given pixel.
Examination of the tilt algorithm shows that the instrument normal is not
unique - the combinations of clock angles, sinkage, and multiple feet lead
to a variety of possible surface normals. However, for the purpose of the
MARSIROUGH program, we need one "most likely" normal. Therefore we choose
the one closest to the center of the clock range, with no sinkage. We do
still look at all combinations of feet, and take the average normal across
those combinations (applies only to HP3 and Heli). Note that no sinkage and
full sinkage result in the same normal, since all feet sink the same amount.
The ZIX_OUT file is a 1-band float file that contains the Z position of the
instrument if it was placed at that location. The Z position is the coordinate
of the point directly below the grapple, in the plane of the feet. Similar to
UIX_OUT, this takes the center of the clock range. Note that it uses the
nominal feet, NOT adjusted for settling. There is a parameter in MARSIROUGH to
include settling if that is desired.
Because the surface normal is an average, using it with the foot locations of
the HP3 or Heli creates more than one solution. In all cases the foot position
is used to fix the Z value of a plane that is normal to the instrument normal,
and then the Z position of the center of the instrument (grapple point for
InSight) is computed. The final Z value is the lowest (highest Z numerically
since +Z is down) of these computed positions - again, modeling the worst
case (since that means more interaction with the terrain).
Parallel Processing
-------------------
This program requires a lot of computational resources - especially delta
tilt. The number of combinations of positions that must be checked can get
quite large. For this reason, the program has been parallelized using
Open MP (OMP), which is built in to the g++ compiler.
By default the number of threads used equals the number of cores on the machine
where the program is being run. Each image line is assigned to a different
core, with "dynamic" scheduling to keep the workload for each core similar.
Parallel processing can be disabled via the -OMP_OFF keyword. The number
of threads can be controlled by setting the OMP_NUM_THREADS environment
variable before running the program. There are numerous other OMP variables
that can be set; see the OMP documentation. However, the number of threads
is the only one that is likely to be useful in most cases.
Implementation Notes
--------------------
The instrument shapes should be in a data file but for now are compiled in
to the program, via marsi_instruments(_h).com.
Clocking is simulated by stepping to different clock values and checking each.
There is a tradeoff between fidelity and execution time. The smaller the clock
steps, the more accurate the result but the slower it runs (dramatically so).
Once an instrument foot point is determined, we must find the pixel that is
closest to that point as a starting point. This is implemented by using a
K-D tree as implemented in the "nanoflann" package. The POINT_EPSILON parameter
determines how far away this point can be from the ideal point (default .004m),
and the LEAF_MAX_SIZE determines how big the leaves of the tree can be before
splitting them.
From there, a region growing algorithm is used to determine all the XYZ points
that belong to the foot. The region spirals out one pixel at a time until a
complete box (one pixel wide) is found with no hits within the confines of the
foot circle. This region growing is bounded by the FOOT_WINDOW parameter; once
the box half-width exceeds the FOOT_WINDOW, the growing stops. This is for
efficiency (to prevent spiraling out to the entire image in pathological
cases), but in practice the window should be set so the entire foot is within
it.
After region growing terminates, the mean and standard deviation of the
points in the region are computed. Outliers (more than FILTER_SCALE * sigma
away from the mean in Z) are rejected. Then the highest point (smallest Z)
amongst the remaining points is retained as the position of the foot. The min
and max tilt are then computed, using a combinations library (combinations.hpp)
to pick up all combinations of feet. All sets of settled/unsettled are
determined using a binary bit mask counting from 0 to 7 (one bit per foot).
Note that for efficiency, the foot Z locations are cached for reuse as they
are computed, since settling and clocking mean each foot location is used
many, many times. The K-D tree must be searched for each foot location,
but once it is determined, the Z of the foot at that spot is computed only
once. There are two separate caches for delta-tilt, since the SEIS and WTS
feet are not the same size.
NOTE: Holes or gaps in the XYZ image are generally ignored. The central
position of each foot has to match the given XYZ coordinate (within
POINT_EPSILON), so holes in the middle of a foot, if big enough, could cause
the location to be rejected. But no analysis is done of other holes in
the area the foot "should" cover. Holes represent unknowns, so normally the
presence of holes would be a red flag for placement. However, the feet are
generally small enough that significant unknown terrain within one foot patch
is unlikely. Also, we look for the maximum within the foot patch, so holes
would have to also be the highest terrain around to cause a problem. However,
it does open the possibility of single pixels representing an entire foot
patch.
TBD Items
---------
TBD!!!!: Improve handling of holes by computing how many pixels the foot
should cover at the given distance and have a percentage threshold to indicate
the maximum number of holes (i.e. minimum coverage of pixels) to allow for a
given location. Perhaps also a threshold for the absolute minimum number of
pixels in a foot patch. Throw out locations that do not meet this criteria.
This is complicated by the potential lack of a camera model (if an ortho XYZ
is input, which is a common use case) - a test would have to be made whether
a camera model was available, and assume a constant iFOV if not.
TBD!!!!: Output labels are not being set correctly.
Note: This program started out as NSYTTILT, an InSight-specific program.
It was multimissionized and renamed MARSITILT. All of the InSight
functionality is in this program; i.e. NSYTTILT could be obsoleted.
HISTORY:
2015-06 S.Myint - Initial version of tilt and delta tilt programs
2015-10 rgd - Nearly complete rewrite; merged tilt and delta tilt
2015-11 rgd - Added clocking; added normal and Z outputs; fixed many
other issues; wrote help.
2016-01 rgd - Added outlier rejection, and caching of foot points
2018-01 Steven Lu - Implement radial and cross-radial offsets for WTS.
2018-07 Steven Lu - Added UPX_OUT and XPX_OUT.
2019-12-23 Walt Bunch - Initialized some variables; cleaned up -Wall warnings.
Added unit test.
2020-05-26 Walt Bunch - Replaced sprintfs.
2020-07 rgd Multimissionized, added M20 helicopter support
COGNIZANT PROGRAMMER: B. Deen
PARAMETERS:
INP
Input XYZ image.
Must be 1 3-band file
or (x,y,z) triplet
OUT
Output file.
Must be 1 filename
UIX_OUT
Optional output
instrument UIX image
ZIX_OUT
Optional output
instrument ZIX image
UPX_OUT
Optional output
instrument UPX image
XPX_OUT
Optional output
instrument XPX image
P_COORD
Coordinate system used
for UPX_OUT and XPX_OUT
parameters
NAVTABLE
Corrected navigation
filename.
INST
Instrument
to use
DELTA
Selects standard or
delta tilt
TILT_THRESHOLD
Maximum allowed tilt
SINKAGE
How much feet can sink
CLOCK_RANGE
Range for clocking
CLOCK_STEP
Step size for clocking
DELTA_WTS_RANGE
Clocking range for WTS
with delta tilt. Defaults
to CLOCK_RANGE
DELTA_WTS_STEP
Step size for clocking
WTS with delta tilt.
Defaults to CLOCK_STEP
WTS_OFF
Radial and cross-radial offsets
between SEIS and WTS
LEAF_MAX_SIZE
Control for KD tree
POINT_EPSILON
Control for KD tree search
FOOT_WINDOW
Window size for foot search
BAD_TILT
Value to use for
invalid tilt
FILTER_SCALE
Sigma multiplier for
outlier rejection filter.
OMP_ON
Turns on or off parallel
processing (default: on)
CONFIG_PATH
Path used to find
configuration/calibration
files.
POINT_METHOD
Specifies a mission-
specific pointing
method to use
NOSITE
Disables coordinate
system sites.
DATA_SET_NAME
Specifies the full name given
to a data set or a data product.
DATA_SET_ID
Specifies a unique alphanumeric
identifier for a data set or data
product.
RELEASE_ID
Specifies the unique identifier
associated with the release to the
public of all or part of a data set.
The release number is associated with
the data set, not the mission.
PRODUCT_ID
Specifies a permanent, unique
identifier assigned to a data
product by its producer.
PRODUCER_ID
Specifies the unique identifier
of an entity associated with the
production a data set.
PRODUCER_INST
Specifies the full name of the
identity of an entity associated
with the production of a data set.
TARGET_NAME
Specifies a target.
TARGET_TYPE
Specifies the type of a named target.
RSF
Rover State File(s) to use.
DEBUG_RSF
Turns on debugging of RSF
parameter.
COORD
Coordinate system to use.
COORD_INDEX
Coordinate system index for
some COORD/mission combos.
FIXED_SITE
Which site is FIXED for
rover missions.
SOLUTION_ID
Solution ID to use for
COORD_INDEX
See Examples:
Cognizant Programmer: