# Variable

Model ElementVariable defines an algebraic state in MotionSolve.

Variable

## Description

The variable may be defined in the three different ways:
• An explicit or implicit function of system state and time defined in a MotionSolve expression.
• An explicit or implicit function of system state and time defined in a compiled DLL.
• An explicit or implicit function of system state and time defined in a user-defined script.

Variables are quite versatile and have many different applications in modeling multibody systems. They are used to create signals of interest in the simulation. The signal may then be used to define forces, create independent variables for interpolation into test data, define inputs to generic control elements, and create complex output signals.

## Attribute Summary

Name Property Modifiable by command? Designable?
id Int ()
label Str () Yes
ic Double () Yes FD Only
implicit Bool (False)   FD Only
auto_balance Enum ("DEFAULT UNCONDITIONAL DISABLED PENALTY", default="DEFAULT")
penalty Double (default=None) Yes FD Only
penalty1 Double (default=None) Yes FD Only
function Function ("VARSUB") Yes
routine Routine ()

## Usage

The three variants of Variable are shown below.
# Defined in a MotionSolve expression
Variable (function=expressionString, optional_attributes)

# Defined in a compiled user subroutine
Variable (function=userString, routine=string, optional_attributes)

# Defined in a Python function
Variable (function=userString, routine=functionPointer, optional_attributes)

## Attributes

function
String defining a valid MotionSolve expression.
Specifies the MotionSolve expression that defines the VARIABLE. Any valid run-time MotionSolve expression can be provided as input.
The function attribute is mandatory.
An explicit or implicit function of system state and time defined in a compiled DLL
function
String defining a valid user function MotionSolve expression.
The list of parameters that are passed from the data file to the user defined subroutine where the Variable is defined.
The function attribute is mandatory.
routine
String
Specifies an alternative name for the user subroutine. The name consists of two pieces of information, separated by "∷". The first is the pathname to the shared library containing the function that computes the response of the user-defined Variable. The second is the name of the function in the shared library that does the computation.
An example is: routine="/staff/Altair/engine.dllmyVariable"
• "/staff/Altair/ engine.dll is the DLL
• "myVariable" is the function within this DLL that performs the calculations
The attribute routine is optional.
When not specified, routine defaults to VARSUB.
An explicit or implicit function of system state and time defined in a user-written Python script
function
String defining a valid user function MotionSolve expression.
The list of parameters that are passed from the data file to the user defined subroutine where the Variable is defined.
The function attribute is mandatory.
routine
Pointer to a callable function in Python
An example is: routine=myVariable
• myVariable is a Python function or method that can be called from wherever the model resides.
The attribute routine is optional.
When not specified, routine defaults to VARSUB.
Optional attributes - Available to all variants
id
Integer
Specifies the element identification number. This number must be unique among all the Variable objects in the model.
This attribute is optional. MotionSolve will automatically create an ID when one is not specified.
Range of values: id > 0
label
String
Specifies the name of the Variable object.
This attribute is optional. When not specified, MotionSolve will create a label for you.

## Examples

1. Compute the Kinetic Energy of a rigid body in an expression.

This example demonstrates how to use an EXPRESSION based Reference_Variable to calculate the kinetic energy of a rigid body. In the example below, the ID of the Reference_Variable is 3070. 1011 is a MARKER that defines the center of mass of a rigid body with mass 4kg and principal moments of inertia Ixx=0.006 Kgm2, Iyy=0.005 Kgm2, and Izz=0.004 Kgm2. Reference_Variable 3070 is the total kinetic energy of the rigid body.

This example demonstrates how to use an EXPRESSION based VARIABLE,
translationalKE = "0.5*(4*vm(1011)**2"
rotationalKE    ="0.006*wx(1011)**2+0.005*wy(1011)**2+0.004*wz(1011)**2)"
KE              = translationalKE " + " rotationalKE
totalKE = Variable (function=KE)
2. Compute the Kinetic Energy of a rigid body in a Python script.
This is the same example solved in the XML section of the description.
# Define the VARSUB, written in Python
def VARSUB(id, time, par, npar, dflag, iflag):

# Get information from the par array
icm  = par[0]
mass = par[1]
ixx  = par[2]
iyy  = par[3]
izz  = par[4]

# get the translational and rotational velocity states
vm   = VM   (icm)
w    = WXYZ (icm)

# Calculate the kinetic energy
if iflag:
totalKE = 0.0
else:
totalKE = 0.5 * (mass*vm**2+ ixx*w[0]**2+ iyy*w[1]**2+ izz*w[2]**2)

# Define the Variable
expr = "User ({id}, 4, 0.006, 0.005, 0.004)".format(id=mrkr3070.id)
Variable (function=expr)
3. Use an implicit VARIABLE to drive a robot.

See Example 3 in the XML syntax for detailed explanations. Here the Python implementation is explained.

Step-1: Define two algebraic constraints that define the motion of Marker 11.
varX = Variable (function="DX(2011)-cubspl(time, 0, 1)", implicit=True,
autobalance="DISABLED", label="X-path of end effector")
varY = Variable (function="DY(2011)-cubspl(time, 0, 2)",implicit=True,
autobalance="DISABLED", label="Y-path of end effector"))

Step-2: Apply the internal force as torques at joints J1 and J2.

Assume that joint J1 is defined with I marker=33, J Marker=44 and joint J2 is defined with I marker=55, J Marker=66
expr1   ="VARVAL({vid})".format(vid=varX.id)
torque1 = Sforce (i=marker33, j=marker44, type="ROTATION", function=expr1)

expr2   ="VARVAL({vid})".format(vid=varY.id)
torque2 = Sforce (i=marker55, j=marker66, type="ROTATION", function=expr2)

Step-3: Look at the torques applied at the Joints to size the motors

varX and varY are the two Variables that apply the torques at joint J1 and J2 respectively. You can look at their values by calling the functions VARVAL(varX.id) and VARVAL(varY.id). These can be used to "size" the motors.

4. Use a Variable to communicate to MATLAB.

See Example 4 in the XML syntax for detailed explanations. Here the Python implementation is explained.

The plant output may be defined as follows:
# Define VARIABLE-12
expr1 ="AY({i}, {j})".format(i=m6565.id, j=m7676.id)
var12 = Variable (function=expr1)

# Define VARIABLE-13
expr2 ="WY({i}, {j})".format(i=m6565.id, j=m7676.id)
var13 = Variable (function=expr2)

# Define the Plant Output
plantOutput = Poutput (variables=[var12, var13])
5. Use a Variable to define a nonlinear relationship in a model.

See Example 5 in the XML syntax for detailed explanations. Here the Python implementation is explained.

Assume that the revolute joint on the steering wheel is defined by I-Marker = m6565 and J-Marker = m7676. The variables defining the steering angle and the steering gear ratio are shown below.
# Define the steering angle
expr1 ="RTOD*ABS(AZ({i}, {j})".format(i=m6565.id, j=m7676.id)
var1  = Variable (function=expr1, label="Steering gear angle in degrees")

# Define the steering gear ratio
expr2 ="step (varval({v}), 100, 1000, 150, 1500".format(v=var1.id)
var2  = Variable (function=expr2, label="Steering gear ratio")
6. Use a Variable to define a "soft" constraint.
See Example 6 in the XML syntax for detailed explanations. Here the Python implementation is explained.
# Compute the violation from the "set point" for the angle and penalize it
expr ="theta({i},{j})-60D".format(i=markerI.id, j=markerJ.id)
var  = Variable (function=expr, penalty=1000, penalty1=10, label="control force")
Force_Penalty is a more natural way to define the soft constraint.
# Compute the violation from the "set point" for the angle and penalize it
expr ="theta({i},{j})-60D".format(i=markerI.id, j=markerJ.id)
controlForce  = Pforce (function=expr, penalty=1000, penalty=10,
auto_balance="PENALTY", label="control force")