public class IKSolver extends java.lang.Object implements PostScannable
Constructor and Description |
---|
IKSolver()
Creates an empty IKSolver.
|
IKSolver(IKSolver solver)
Creates an IKSolver which is a copy of another IKSolver.
|
IKSolver(MechModel mech,
java.util.Collection<FrameMarker> mkrs)
Creates an IKSolver for a set of markers contained within a prescribed
MechModel . |
IKSolver(MechModel mech,
java.util.Collection<FrameMarker> mkrs,
VectorNd weights)
Creates an IKSolver for a set of markers contained within a prescribed
MechModel . |
Modifier and Type | Method and Description |
---|---|
double |
avgNumIterations()
Return the average number of iterations per solve
|
void |
clearSolveCounts()
Clears the cummulative solve and iteration counts.
|
PositionInputProbe |
createBodyPoseProbe(java.lang.String name,
NumericProbeBase targProbe,
RotationRep rotRep,
double interval)
Creates an input probe for controlling the poses of the bodies associated
with this solver.
|
PositionInputProbe |
createBodyPoseProbe(java.lang.String name,
java.lang.String targDataFilePath,
RotationRep rotRep,
double interval)
Creates an input probe for controlling the poses of the bodies associated
with this solver.
|
PositionInputProbe |
createMarkerPositionProbe(java.lang.String name,
NumericProbeBase targProbe,
double interval)
Creates an input probe for controlling the positions of the markers
associated with this solver.
|
PositionInputProbe |
createMarkerPositionProbe(java.lang.String name,
java.lang.String targDataFilePath,
double interval)
Creates an input probe for controlling the positions of the markers
associated with this solver.
|
java.util.ArrayList<RigidBody> |
getBodies()
Returns the bodies associated with this IKSolver.
|
java.util.ArrayList<BodyConnector> |
getConnectors()
Returns the connectors associated with this IKSolver.
|
double |
getConvergenceTol()
Queries the convergance tolerance used in each solve step.
|
java.util.ArrayList<FrameMarker> |
getMarkers()
Returns the markers used by this IKSolver.
|
VectorNd |
getMarkerWeights()
Returns the marker weights used by this IKSolver.
|
double |
getMassRegularization()
Queries the mass regulaization coefficient for this solver.
|
int |
getMaxIterations()
Queries the maximum number of iterations allowed in each solve step.
|
MechModel |
getMechModel()
Returns the MechModel associated with this IKSolver.
|
boolean |
isWritable()
Returns
true if this component should in fact be written to
secondary storage. |
int |
numBodies()
Queries the number of rigid bodies associated with this solver.
|
int |
numIterations()
Return the cummulative number of solve iterations.
|
int |
numMarkers()
Returns the number of markers used by this IKSolver.
|
int |
numSolves()
Return the cummulative number of solves.
|
void |
postscan(java.util.Deque<ScanToken> tokens,
CompositeComponent ancestor)
Performs any required post-scanning for this component.
|
void |
restoreModelState()
Restores the state of the MechModel.
|
void |
saveModelState()
Saves the current state of the MechModel.
|
void |
scan(ReaderTokenizer rtok,
java.lang.Object ref)
Scans this element from a ReaderTokenizer.
|
void |
setBodiesDynamic(boolean dynamic)
Sets the
dynamic property of all the bodies associated
with this solver. |
void |
setConvergenceTol(double tol)
Sets the convergance tolerance
tol used in each solve step. |
void |
setMarkerWeights(VectorNd weights)
Sets the marker weights used by this IKSolver.
|
void |
setMassRegularization(double c)
Sets the mass regularization coefficent
c for this solver. |
void |
setMaxIterations(int maxi)
Set the maximum number of iterations allowed in each solve step.
|
int |
solve(VectorNd mtargs)
Updates the positions of the bodies associated with this solver to bring
the markers as close as possible to the target positions specified by
mtargs . |
void |
write(java.io.PrintWriter pw,
NumberFormat fmt,
java.lang.Object ref)
Writes a text description of this element to a PrintWriter.
|
public IKSolver()
public IKSolver(MechModel mech, java.util.Collection<FrameMarker> mkrs)
MechModel
. All markers are assumed to have a weight of 1. The
rigid bodies and connectors are determined automatically from the
markers. The frames associated with each marker must be a rigid body, and
the set of all such bodies is known as the marker bodies. The
bodies whose positions are updating by the solver includes the marker
bodies, plus any other rigid bodies bodies connected to them via BodyConnector
s, up to and excluding any rigid body whose grounded
property is set to true
.mech
- MechModel containing the markers and bodiesmkrs
- markers determining which bodies will be controlledpublic IKSolver(MechModel mech, java.util.Collection<FrameMarker> mkrs, VectorNd weights)
MechModel
. Markers weights can be specified by the optional
vector weights
. The rigid bodies and connectors are determined
automatically from the markers. The frames associated with each marker
must be a rigid body, and the set of all such bodies is known as the
marker bodies. The bodies whose positions are updating by the
solver includes the marker bodies, plus any other rigid bodies bodies
connected to them via BodyConnector
s, up to and excluding any
rigid body whose grounded
property is set to true
.mech
- MechModel containing the markers and bodiesmkrs
- markers determining which bodies will be controlledweights
- if non-null
, specifies weights for the markerspublic IKSolver(IKSolver solver)
solver
- IKSolver to copypublic double getMassRegularization()
setMassRegularization(double)
public void setMassRegularization(double c)
c
for this solver. The
default value is 0.001.
Each body is associated with a solve matrix defined by J^T J
,
where J
is the matrix mapping differential changes in body pose
to changes in marker position. This matrix provides the Hessian for the
minimization. If the number of markers is less than 3, or if the markers
all lie along a line, the solve matrix will be rank deficient. In that
case, regularization terms are added to the matrix in such a way as to
make it non-singular while preserving its range space. The size of these
terms, relative to the weight of the matrix itself, is given by c
.
c
- mass regulaization coefficientgetMassRegularization()
public int getMaxIterations()
setMaxIterations(int)
public void setMaxIterations(int maxi)
maxi
- maximum number of solve iterationsgetMaxIterations()
public double getConvergenceTol()
public void setConvergenceTol(double tol)
tol
used in each solve step. A
solve step will be considered converged with the incremental translation
and rotation for all bodies is less then tol*bodyLen
and
tol
, respectively, where bodyLen
is the charateristic
length of the body as inferrd from its spatial inertia. The
default value of tol
is 1e-8
.
#see #getConvergenceToltol
- convergence tolerancepublic java.util.ArrayList<RigidBody> getBodies()
public int numBodies()
public void setBodiesDynamic(boolean dynamic)
dynamic
property of all the bodies associated
with this solver.dynamic
- setting for each body's dynamic
propertypublic java.util.ArrayList<FrameMarker> getMarkers()
public int numMarkers()
public VectorNd getMarkerWeights()
public void setMarkerWeights(VectorNd weights)
weights
- new marker weightspublic MechModel getMechModel()
public java.util.ArrayList<BodyConnector> getConnectors()
public int solve(VectorNd mtargs)
mtargs
.mtargs
- target positions for each marker. Should have a size >= 3*numMarkers()
.public void saveModelState()
public void restoreModelState()
public int numIterations()
public int numSolves()
public double avgNumIterations()
public void clearSolveCounts()
public boolean isWritable()
true
if this component should in fact be written to
secondary storage. This gives subclasses control over whether or
not they are actually written out.isWritable
in interface Scannable
true
if this component should be written to
secondary storage.public void write(java.io.PrintWriter pw, NumberFormat fmt, java.lang.Object ref) throws java.io.IOException
scan
and complete
enough to allow full reconstruction of the element.public void scan(ReaderTokenizer rtok, java.lang.Object ref) throws java.io.IOException
write
.public void postscan(java.util.Deque<ScanToken> tokens, CompositeComponent ancestor) throws java.io.IOException
scan()
method and stored in the token queue.
The most common use of this method is to resolve the paths
of component references, which may not have been created
at the time of the initial scan()
call.postscan
in interface PostScannable
tokens
- token information that was stored during
scan()
.ancestor
- ancestor component with respect to which
reference component paths are defined.java.io.IOException
- if an error is encountered (such as a reference to a
non-existent component)public PositionInputProbe createBodyPoseProbe(java.lang.String name, java.lang.String targDataFilePath, RotationRep rotRep, double interval) throws java.io.IOException
The vector size of the data in this file must be 3 *
numMarkers()
. The start and stop times and scale of the created probe is
also determined from the data file. Knots are added to the probe at a
time interval specified by interval
; if this is given as -1
, then the knot times are the same as those in the data file.
The state of the MechModel associated with this solver is saved before the solve and restored afterward.
name
- if non-null
, specifies the probe's nametargDataFilePath
- path name of the probe data file containing
the target marker positionsrotRep
- rotation representation for the body orientationsinterval
- knot time spacing interval, or -1
if knot
times should be determined from the data filejava.io.IOException
- if an I/O error occurs reading the data filepublic PositionInputProbe createBodyPoseProbe(java.lang.String name, NumericProbeBase targProbe, RotationRep rotRep, double interval)
targProbe
.
The vector size of the data in mkrdata
must be 3 *
numMarkers()
. The start and stop times and scale of the created probe is
also determined from mkrdata
. Knots are added to the probe at a
time interval specified by interval
; if this is given as -1
, then the knot times are the same as those in mkrdata
.
The state of the MechModel associated with this solver is saved before the solve and restored afterward.
name
- if non-null
, specifies the probe's nametargProbe
- probe containing target position data for the markersrotRep
- rotation representation for the body orientationsinterval
- knot time spacing interval, or -1
if knot
times should be determined from mrkdata
public PositionInputProbe createMarkerPositionProbe(java.lang.String name, java.lang.String targDataFilePath, double interval) throws java.io.IOException
The vector size of the data in this file must be 3 *
numMarkers()
. The start and stop times and scale of the created probe is
also determined from the data file. Knots are added to the probe at a
time interval specified by interval
; if this is given as -1
, then the knot times are the same as those in the data file.
The state of the MechModel associated with this solver is saved before the solve and restored afterward.
name
- if non-null
, specifies the probe's nametargDataFilePath
- path name of the probe data file containing
the target marker positionsinterval
- knot time spacing interval, or -1
if knot
times should be determined from the data file.java.io.IOException
- if an I/O error occurs reading the data filepublic PositionInputProbe createMarkerPositionProbe(java.lang.String name, NumericProbeBase targProbe, double interval)
targProbe
. Effectively, this method takes marker data stored in
targProbe
and filters it for kinematic feasibility.
The vector size of the data in mkrdata
must be 3 *
numMarkers()
. The start and stop times and scale of the created probe is
also determined from mkrdata
. Knots are added to the probe at a
time interval specified by interval
; if this is given as -1
, then the knot times are the same as those in mkrdata
.
The state of the MechModel associated with this solver is saved before the solve and restored afterward.
name
- if non-null
, specifies the probe's nametargProbe
- probe containing target position data for the markersinterval
- knot time spacing interval, or -1
if knot
times should be determined from mrkdata