Rigid Body Dynamics Library
SmoothSegmentedFunction Class Reference

#include <SmoothSegmentedFunction.h>

+ Inheritance diagram for SmoothSegmentedFunction:

Public Member Functions

 SmoothSegmentedFunction ()
 
 SmoothSegmentedFunction (const RigidBodyDynamics::Math::MatrixNd &mX, const RigidBodyDynamics::Math::MatrixNd &mY, double x0, double x1, double y0, double y1, double dydx0, double dydx1, const std::string &name)
 
void updSmoothSegmentedFunction (const RigidBodyDynamics::Math::MatrixNd &mX, const RigidBodyDynamics::Math::MatrixNd &mY, double x0, double x1, double y0, double y1, double dydx0, double dydx1, const std::string &name)
 
void shift (double xShift, double yShift)
 
void scale (double xScale, double yScale)
 
double calcValue (double x) const
 
double calcInverseValue (double y, double xGuess) const
 
double calcDerivative (double x, int order) const
 
std::string getName () const
 
void setName (const std::string &name)
 
RigidBodyDynamics::Math::VectorNd getCurveDomain () const
 
void printCurveToCSVFile (const std::string &path, const std::string &fileNameWithoutExtension, double domainMin, double domainMax) const
 
RigidBodyDynamics::Math::MatrixNd calcSampledCurve (int maxOrder, double domainMin, double domainMax) const
 
void getXControlPoints (RigidBodyDynamics::Math::MatrixNd &mat) const
 
void getYControlPoints (RigidBodyDynamics::Math::MatrixNd &mat) const
 
- Public Member Functions inherited from Function_< double >
virtual ~Function_ ()
 
virtual double calcValue (const RigidBodyDynamics::Math::VectorNd &x) const=0
 
virtual double calcDerivative (const std::vector< int > &derivComponents, const RigidBodyDynamics::Math::VectorNd &x) const=0
 
virtual int getArgumentSize () const=0
 
virtual int getMaxDerivativeOrder () const=0
 

Private Member Functions

void printMatrixToFile (RigidBodyDynamics::Math::MatrixNd &data, std::vector< std::string > &colnames, const std::string &path, const std::string &filename) const
 
double calcValue (const RigidBodyDynamics::Math::VectorNd &x) const
 
double calcDerivative (const std::vector< int > &derivComponents, const RigidBodyDynamics::Math::VectorNd &x) const
 
int getArgumentSize () const
 
int getMaxDerivativeOrder () const
 

Private Attributes

std::vector< RigidBodyDynamics::Math::VectorNd_mXVec
 
std::vector< RigidBodyDynamics::Math::VectorNd_mYVec
 
int _numBezierSections
 
double _x0
 
double _x1
 
double _y0
 
double _y1
 
double _dydx0
 
double _dydx1
 
std::string _name
 

Friends

class SmoothSegmentedFunctionFactory
 

Detailed Description

Definition at line 89 of file SmoothSegmentedFunction.h.

Constructor & Destructor Documentation

◆ SmoothSegmentedFunction() [1/2]

The default constructor, which populates the member data fields with NaN's

◆ SmoothSegmentedFunction() [2/2]

SmoothSegmentedFunction ( const RigidBodyDynamics::Math::MatrixNd mX,
const RigidBodyDynamics::Math::MatrixNd mY,
double  x0,
double  x1,
double  y0,
double  y1,
double  dydx0,
double  dydx1,
const std::string &  name 
)

Creates a set of quintic Bezier curves.

Parameters
mXThe matrix of quintic Bezier x point locations (6xn). Each column vector is the 6 control points required for each quintic Bezier curve. For C0 continuity adjacent columns must share the last and first control points. For C1 continuity the last 2 and first two control points of adjacent curves should be on the same curve.
mYThe matrix of quintic Bezier y point locations (6xn).
x0The minimum x value. This is used for the linear extrapolation of the Bezier curve. This parameter is explicitly asked for, rather than computed, to prevent rounding error from reducing the accuracy of the linear extrapolation.
x1The maximum x value. This is used for the linear extrapolation and is required for the same reasons as x0.
y0The value of y(x) at x=x0. This is used for the linear extrapolation and is required for the same reasons as x0.
y1The value of y(x) at x=x1. This is used for the linear extrapolation and is required for the same reasons as x0.
dydx0The value of dy/dx at x=x0. This is used for the linear extrapolation and is required for the same reasons as x0.
dydx1The value of dy/dx at x=x1. This is used for the linear extrapolation and is required for the same reasons as x0.
nameThe name of the data this SmoothSegmentedFunction. This name is used to make human-readable error messages and to generate sensible names when printing the curve to file.

Computational Costs Generating the integral curve is not cheap, and so should only be used when if it will be evaluated during a simulation.

Computatonal Cost Per Bezier Section:
  Without Integral :   4,100 flops


Member Function Documentation

◆ calcDerivative() [1/2]

double calcDerivative ( const std::vector< int > &  derivComponents,
const RigidBodyDynamics::Math::VectorNd x 
) const
privatevirtual

Refer to the documentation for calcDerivative(double x, int order) because this function is identical in function to calcDerivative(double x, int order), but requires different inputs. This is a required virtual function required because this class extends the Function interface.

Implements Function_< double >.

◆ calcDerivative() [2/2]

double calcDerivative ( double  x,
int  order 
) const

Calculates the value of the derivative of the curve this object represents.

Parameters
xThe domain point of interest.
orderThe order of the derivative to compute. Note that order must be between 0 and 2. Calling 0 just calls calcValue.

aborts -If anything but 0's are stored in derivComponents -If more than the 6th derivative is asked for -If ax has a size other than 1

Returns
The value of the d^ny/dx^n th derivative evaluated at x

Computational Costs

  x in curve domain  : ~391 flops
  x in linear section:   ~2 flops   

◆ calcInverseValue()

double calcInverseValue ( double  y,
double  xGuess 
) const

This function solves for the x value of the curve given its y value. Since a SmoothSegmentedFunction is not necessarily monotonic lower and an upper bound on the argument must be specified so that the desired root is found.

Parameters
yThe range value of interest
xGuessguess for the value of x
Returns
x: the value of x which corresponds to y = f(x) between xLowerBound, and xUpperBound

◆ calcSampledCurve()

RigidBodyDynamics::Math::MatrixNd calcSampledCurve ( int  maxOrder,
double  domainMin,
double  domainMax 
) const
Parameters
maxOrderThe maximum derivative order to compute
domainMin
domainMaxaborts -If the requested derivatve order is greater than getMaxDerivativeOrder()
Returns
a matrix populated with x,y,dy/dx ... d^ny/dx^n,iy

This function will generate a RigidBodyDynamics::Math::MatrixNd populated with samples of the muscle curves values, derivatives (up to 6) and its first integral (if available). The matrix has the following columns:

 Col# 1, 2,   3,   4,   5,   6,   7,   8, 9,
  x, y, dy/dx, d2y/dx2, d3y/dx3, d4y/dx4, d5y/dx5, d6y/dx6, iy

Where iy is the integral of y(x). If the curve has been set not to have an integral, this column will not exist.

The curve will be sampled from its linear extrapolation region, through the curve, out to the other linear extrapolation region. The width of each linear extrapolation region is 10% of the entire range of x, or 0.1*(x1-x0).

The rows used will vary from curve to curve. Each quintic Bezier curve section will have 100 samples + 20 samples for the linear extrapolation region. Some muscle curves (the tendon, parallel elements, compressive elements) consist of only 1 elbow, and so these matrices will have only 100+20 rows. The force velocity curve is made up of 2 elbows and will have 200+20 rows. The active force length curve has 5 elbows, and so its sampled matrix will have 500+20 rows

◆ calcValue() [1/2]

double calcValue ( const RigidBodyDynamics::Math::VectorNd x) const
privatevirtual

Refer to the documentation for calcValue(double x) because this function is identical in function to calcValue(double x), but requires different inputs. This is a required virtual function required because this class extends the Function interface.

Implements Function_< double >.

◆ calcValue() [2/2]

double calcValue ( double  x) const

Calculates the value of the curve this object represents.

Parameters
xThe domain point of interest

aborts -If ax does not have a size of 1

Returns
The value of the curve

The curve is parameterized as a set of Bezier curves. If x is within the domain of these Bezier curves they will be evaluated. If x is outside of the domain of these Bezier curves a linear extrapolation will be evalulated

Computational Costs

  x in curve domain  : ~282 flops
  x in linear section:   ~5 flops

◆ getArgumentSize()

int getArgumentSize ( ) const
privatevirtual

This will return the size of the vector that the calcValue(const RigidBodyDynamics::Math::VectorNd& x) require. This is a required virtual function required because this class extends the Function interface, though is only needed if you call

double calcValue(const RigidBodyDynamics::Math::VectorNd& x) const;

or

double calcDerivative( const SimTK::Array_<int>& derivComponents, const RigidBodyDynamics::Math::VectorNd& x) const;

Since this class is implementing strictly scalar functions you can use the simplified versions of calcValue(double x) and calcDerivative(double x, int order) instead.

Implements Function_< double >.

◆ getCurveDomain()

RigidBodyDynamics::Math::VectorNd getCurveDomain ( ) const

This function returns a SimTK::Vec2 that contains in its 0th element the lowest value of the curve domain, and in its 1st element the highest value in the curve domain of the curve. Outside of this domain the curve is approximated using linear extrapolation.

Returns
The minimum and maximum value of the domain, x, of the curve y(x). Within this range y(x) is a curve, outside of this range the function y(x) is a C2 (continuous to the second derivative) linear extrapolation

◆ getMaxDerivativeOrder()

int getMaxDerivativeOrder ( ) const
privatevirtual
Returns
The maximum order derivative that this object is capable of returning

Implements Function_< double >.

◆ getName()

std::string getName ( ) const

Returns a string that is the name for this curve, which is set at the time of construction and cannot be changed after construction.

Returns
The string name this object was given during construction

◆ getXControlPoints()

void getXControlPoints ( RigidBodyDynamics::Math::MatrixNd mat) const

◆ getYControlPoints()

void getYControlPoints ( RigidBodyDynamics::Math::MatrixNd mat) const

◆ printCurveToCSVFile()

void printCurveToCSVFile ( const std::string &  path,
const std::string &  fileNameWithoutExtension,
double  domainMin,
double  domainMax 
) const

This function will generate a csv file (of 'name_curveName.csv', where name is the one used in the constructor) of the muscle curve, and 'curveName' corresponds to the function that was called from SmoothSegmentedFunctionFactory to create the curve.

Parameters
pathThe full path to the location. Note '/' slashes must be used, and do not put a '/' after the last folder.
fileNameWithoutExtensionThe name of the file to write, not including the file extension
domainMinthe left most domain point of the curve to print. The curve will extend to at least this point.
domainMaxthe right most domain point of the curve to print. The printed curve will extend at least to this point, perhaps beyond. aborts -If the filename is empty

For example the tendon curve for a muscle named 'glutmax' will be:

'glutmax_tendonForceLengthCurve.csv'

The file will contain the following columns:

 Col# 1, 2,   3,   4,  5
  x, y, dy/dx, d2y/dx2,  iy

Where iy is the integral of y(x). If the curve has been set not to have an integral, this column will not exist.

The curve will be sampled from its linear extrapolation region, through the curve, out to the other linear extrapolation region. The width of each linear extrapolation region is 10% of the entire range of x, or 0.1*(x1-x0).

The number of rows used will vary from curve to curve. Each quintic Bezier curve section will have 100 samples. Each linearily extrapolated region will have 10 samples each. Some muscle curves (the tendon, parallel elements, compressive elements) consist of only 1 elbow, and so these matrices will have only 100+20 rows. The force velocity curve is made up of 2 elbows and will have 200+20 rows. The active force length curve has 5 elbows, and so its sampled matrix will have 500+20 rows

Computational Costs This varies depending on the curve (as mentioned above).

  ~97,400 to 487,000 flops

Example To read the csv file with a header in from Matlab, you need to use csvread set so that it will ignore the header row. This is accomplished by using the extra two numerical arguments for csvread to tell the function to begin reading from the 1st row, and the 0th index (csvread is 0 indexed).

data=csvread('test_tendonForceLengthCurve.csv',1,0);

◆ printMatrixToFile()

void printMatrixToFile ( RigidBodyDynamics::Math::MatrixNd data,
std::vector< std::string > &  colnames,
const std::string &  path,
const std::string &  filename 
) const
private

This function will print cvs file of the column vector col0 and the matrix data

Parameters
dataA matrix of data
colnamesArray of column headings
pathThe desired path to the folder to write the file
filenameThe name of the file to print aborts -If the desired file cannot be created and openened, perhaps because the path doesn't exist.

◆ scale()

void scale ( double  xScale,
double  yScale 
)

This function will scale the curve in the x and y directions. Setting xScale=yScale=1.0 will leave the curve unchanged.

aborts -If abs(xScale) < sqrt(eps)

Parameters
xScalethe amount to scale the curve in the x direction
yScalethe amount to scale the curve in the y direction

◆ setName()

void setName ( const std::string &  name)

Sets the name of the SmoothSegmentedFunction object.

Parameters
nameThe name of the data this SmoothSegmentedFunction. This name is used to make human-readable error messages and to generate sensible names when printing the curve to file.

◆ shift()

void shift ( double  xShift,
double  yShift 
)

This function will shift the entire SmoothSegmentedFunction by xShift and yShift. Setting xShift = yShift = 0.0 will leave the curve unchanged.

Parameters
xShift- the amount to shift the curve in the x-direction.
yShift- the amount to shift the curve in the y-direction

◆ updSmoothSegmentedFunction()

void updSmoothSegmentedFunction ( const RigidBodyDynamics::Math::MatrixNd mX,
const RigidBodyDynamics::Math::MatrixNd mY,
double  x0,
double  x1,
double  y0,
double  y1,
double  dydx0,
double  dydx1,
const std::string &  name 
)

Updates the Bezier curve conrol points. The updated curve must have the same number of control points as the original curve.

Parameters
mXThe matrix of quintic Bezier x point locations (6xn). Each column vector is the 6 control points required for each quintic Bezier curve. For C0 continuity adjacent columns must share the last and first control points. For C1 continuity the last 2 and first two control points of adjacent curves should be on the same curve.
mYThe matrix of quintic Bezier y point locations (6xn).
x0The minimum x value. This is used for the linear extrapolation of the Bezier curve. This parameter is explicitly asked for, rather than computed, to prevent rounding error from reducing the accuracy of the linear extrapolation.
x1The maximum x value. This is used for the linear extrapolation and is required for the same reasons as x0.
y0The value of y(x) at x=x0. This is used for the linear extrapolation and is required for the same reasons as x0.
y1The value of y(x) at x=x1. This is used for the linear extrapolation and is required for the same reasons as x0.
dydx0The value of dy/dx at x=x0. This is used for the linear extrapolation and is required for the same reasons as x0.
dydx1The value of dy/dx at x=x1. This is used for the linear extrapolation and is required for the same reasons as x0.
nameThe name of the data this SmoothSegmentedFunction. This name is used to make human-readable error messages and to generate sensible names when printing the curve to file.

Friends And Related Function Documentation

◆ SmoothSegmentedFunctionFactory

friend class SmoothSegmentedFunctionFactory
friend

No human should be constructing a SmoothSegmentedFunction, so the constructor is made private so that mere mortals cannot look at it. SmoothSegmentedFunctionFactory should be used to create MuscleCurveFunctions and that's why its a friend

Definition at line 525 of file SmoothSegmentedFunction.h.

Field Documentation

◆ _dydx0

double _dydx0
private

The slope at _x0

Definition at line 508 of file SmoothSegmentedFunction.h.

◆ _dydx1

double _dydx1
private

The slope at _x1

Definition at line 510 of file SmoothSegmentedFunction.h.

◆ _mXVec

std::vector<RigidBodyDynamics::Math::VectorNd> _mXVec
private

Nov 2015: Not needed in the RBDL port. Array of spline fit functions X(u) for each Bezier elbow Nov 2015: Not included in the RBDL port (RBDL doesn't have an error controlled integrator to generate this curve) Spline fit of the integral of the curve y(x) Bezier X1,...,Xn control point locations. Control points are stored in 6x1 vectors in the order above

Definition at line 491 of file SmoothSegmentedFunction.h.

◆ _mYVec

std::vector<RigidBodyDynamics::Math::VectorNd> _mYVec
private

Bezier Y1,...,Yn control point locations. Control points are stored in 6x1 vectors in the order above

Definition at line 494 of file SmoothSegmentedFunction.h.

◆ _name

std::string _name
private

The name of the function

Definition at line 519 of file SmoothSegmentedFunction.h.

◆ _numBezierSections

int _numBezierSections
private

The number of quintic Bezier curves that describe the relation

Definition at line 497 of file SmoothSegmentedFunction.h.

◆ _x0

double _x0
private

The minimum value of the domain

Definition at line 500 of file SmoothSegmentedFunction.h.

◆ _x1

double _x1
private

The maximum value of the domain

Definition at line 502 of file SmoothSegmentedFunction.h.

◆ _y0

double _y0
private

The minimum value of the range

Definition at line 504 of file SmoothSegmentedFunction.h.

◆ _y1

double _y1
private

The maximum value of the range

Definition at line 506 of file SmoothSegmentedFunction.h.


The documentation for this class was generated from the following file: