Back

FrameSpringForceField

The `FrameSpringForceField` is a SOFA (Simulation Open-Framework Architecture) component that simulates 6D springs between moving frames, typically used in rigid body dynamics simulations.

abstract
The `FrameSpringForceField` simulates 6D springs between rigid bodies with parameters for translational and rotational stiffness and damping. It computes forces and torques based on the deformation of connected frames.
sheet
# FrameSpringForceField ## Overview The `FrameSpringForceField` is a component in SOFA that simulates 6D springs (three translational and three rotational degrees of freedom) between rigid bodies. This component inherits from `PairInteractionForceField` and is used to model elastic interactions in rigid body dynamics simulations. ## Mathematical Model Each spring connects two rigid bodies at specific points, defined by indices `m1` and `m2`. The stiffness parameters for each spring are `stiffnessTrans`, which affects the translational degrees of freedom, and `stiffnessRot`, which affects the rotational degrees of freedom. Additionally, a damping factor `kd` can be applied to dissipate energy in the system. ### Force Calculation The force due to translational deformation is computed using: egin{equation} \mathbf{F}_{trans} = -k_{st}(\mathbf{x}_1 + \vec{r_1} - (\mathbf{x}_2 + \vec{r_2})) \end{equation} where $\mathbf{x}_1$ and $\mathbf{x}_2$ are the positions of the rigid bodies, $\vec{r_1}$ and $\vec{r_2}$ are vectors along the translational DOFs from the body's center to the spring attachment points, and $k_{st}$ is the stiffnessTrans parameter. The torque due to rotational deformation is calculated using: egin{equation} \mathbf{T}_{rot} = -k_{sr}(\mathbf{R}_1 \cdot \vec{v_1} - (\mathbf{R}_2 \cdot \vec{v_2})) \end{equation} where $\mathbf{R}_1$ and $\mathbf{R}_2$ are rotation matrices representing the orientations of the rigid bodies, $\vec{v_1}$ and $\vec{v_2}$ are vectors along the rotational DOFs from the body's center to the spring attachment points, and $k_{sr}$ is the stiffnessRot parameter. ### Damping Damping force/torque due to velocity differences can be added as follows: egin{equation} \mathbf{F}_{damp} = -kd(\dot{\mathbf{x}}_1 + \vec{r_1} - (\dot{\mathbf{x}}_2 + \vec{r_2})) \\ \mathbf{T}_{damp} = -kd(\dot{\mathbf{R}}_1 \cdot \vec{v_1} - (\dot{\mathbf{R}}_2 \cdot \vec{v_2})) \end{equation} ### Potential Energy The potential energy stored in the spring is given by: egin{equation} U = \frac{1}{2}k_{st}|(\mathbf{x}_1 + \vec{r_1}) - (\mathbf{x}_2 + \vec{r_2})|^2 + \frac{1}{2}k_{sr}|(\mathbf{R}_1 \cdot \vec{v_1}) - (\mathbf{R}_2 \cdot \vec{v_2})|^2 \end{equation} ## Practical Notes The `FrameSpringForceField` is particularly useful in simulating elastic structures or connections between rigid components. Care should be taken to ensure that the stiffness and damping parameters are chosen appropriately for numerical stability.
description
The `FrameSpringForceField` is a SOFA (Simulation Open-Framework Architecture) component that simulates 6D springs between moving frames, typically used in rigid body dynamics simulations.
parameters
  • {'name': '`d_springs`', 'type': 'sofa::type::vector<Spring>', 'description': 'A list of spring objects. Each Spring object holds information about a specific spring including the indices of the two extremities (m1 and m2), stiffness for translation (`stiffnessTrans`) and rotation (`stiffnessRot`), damping factor (`kd`), initial vectors vec1 and vec2 that define the orientation in space.'}
  • {'name': '`d_showLawfulTorsion`', 'type': 'Data<bool>', 'description': 'A boolean to allow the display of the lawful part (expected behavior) of torsions in the spring joints. This can be useful for visual debugging purposes.'}
  • {'name': '`d_showExtraTorsion`', 'type': 'Data<bool>', 'description': 'A boolean to display the extra or illicit parts of the joint rotations that go beyond what is allowed by the defined constraints. Again, useful for debugging and understanding the behavior of joints.'}
methods
  • {'name': '`init()`', 'description': 'Initializes the `FrameSpringForceField` component. Typically sets up necessary variables or performs any required setup.'}
  • {'name': '`addForce(...)`', 'description': 'Calculates and adds forces on the mechanical model according to spring properties, current positions, velocities of objects connected by springs. This method updates the force fields `f1` and `f2` based on the specified MechanicalParams.'}
  • {'name': '`addDForce(...)`', 'description': 'Applies stiffness by accumulating changes in forces (`df`) given changes in positions (`dx`). It implements how the system responds to small displacements, which is crucial for solving the mechanical equations of motion.'}
  • {'name': '`buildDampingMatrix(...)`', 'description': 'Sets up or updates the damping matrix. Damping accounts for energy loss due to friction and other dissipative forces in a physical simulation. This function is called during system setup or whenever damping parameters change.'}
  • {'name': '`getPotentialEnergy(...)`', 'description': 'Calculates the potential energy of the mechanical model associated with the current configuration of springs. The result depends on the stiffness and displacements from rest positions.'}
  • {'name': '`draw(...)`', 'description': 'Renders visual representation of the `FrameSpringForceField`, including the position, orientation and possible states (like lawful vs extra torsion) of its components for visual debugging or presentation purposes.'}
interaction_methods
  • {'name': '`addSpring(...)`', 'description': 'Adds a new spring to the system with specified parameters like indices of connected rigid bodies (`m1`, `m2`), stiffness, damping coefficient and initial vectors defining orientation. This method allows dynamic addition of constraints during simulation setup or runtime.'}
  • {'name': '`clear()`', 'description': 'Removes all springs from the system. Optionally, reserves space in the internal vector to hold a specific number of spring objects (default: 0). Useful for resetting the system before reconfiguration.'}
notes
  • The `FrameSpringForceField` class is specialized for use with rigid body types (`Rigid3Types`). It inherits from `PairInteractionForceField`, indicating that it models interactions between pairs of mechanical systems. The component uses internal data structures to store references and intermediate computations, aiding in efficient force calculations.
examples_of_use
  • This component can be used to model flexible connectors or constraints within a robotic arm simulation where each segment is represented as a rigid body, allowing for realistic movement and collision responses.
  • In biomechanics simulations, it can simulate ligaments connecting bones with specific stiffness properties that affect the overall motion.
dependencies
  • SOFA core
  • behavior module
  • visual module
maths
## Mathematical and Physical Description of FrameSpringForceField The `FrameSpringForceField` in the SOFA framework simulates springs between moving frames (rigid bodies) with six degrees of freedom (DOF), including three translational and three rotational DOFs. This component is used to model elastic interactions in rigid body simulations. ### Springs Between Moving Frames Each spring connects two rigid bodies (or frames) at specific points, defined by the indices `m1` and `m2`. The stiffness parameters for each spring are `stiffnessTrans`, which affects the translational degrees of freedom, and `stiffnessRot`, which affects the rotational degrees of freedom. Additionally, a damping factor `kd` can be applied to dissipate energy in the system. ### Force Calculation The force and torque exerted by each spring on the connected rigid bodies is calculated based on their current positions and orientations relative to their initial configuration. The force due to translational deformation is computed using: $$ \mathbf{F}_{trans} = -k_{st}(\mathbf{x}_1 + \vec{r_1} - (\mathbf{x}_2 + \vec{r_2})) $$ where $\mathbf{x}_1$ and $\mathbf{x}_2$ are the positions of the rigid bodies, $\vec{r_1}$ and $\vec{r_2}$ are vectors along the translational DOFs from the body's center to the spring attachment points, and $k_{st}$ is the stiffnessTrans parameter. The torque due to rotational deformation is calculated using: $$ \mathbf{T}_{rot} = -k_{sr}(\mathbf{R}_1 \cdot \vec{v_1} - (\mathbf{R}_2 \cdot \vec{v_2})) $$ where $\mathbf{R}_1$ and $\mathbf{R}_2$ are rotation matrices representing the orientations of the rigid bodies, $\vec{v_1}$ and $\vec{v_2}$ are vectors along the rotational DOFs from the body's center to the spring attachment points, and $k_{sr}$ is the stiffnessRot parameter. ### Damping Damping force/torque due to velocity differences can be added as follows: $$ \mathbf{F}_{damp} = -kd(\dot{\mathbf{x}}_1 + \vec{r_1} - (\dot{\mathbf{x}}_2 + \vec{r_2})) \\ \mathbf{T}_{damp} = -kd(\dot{\mathbf{R}}_1 \cdot \vec{v_1} - (\dot{\mathbf{R}}_2 \cdot \vec{v_2})) $$ ### Potential Energy The potential energy stored in the spring is given by: $$ U = \frac{1}{2}k_{st}|(\mathbf{x}_1 + \vec{r_1}) - (\mathbf{x}_2 + \vec{r_2})|^2 + \frac{1}{2}k_{sr}|(\mathbf{R}_1 \cdot \vec{v_1}) - (\mathbf{R}_2 \cdot \vec{v_2})|^2 $$ ### Application in SOFA In the SOFA framework, this component is used to create physical interactions between rigid bodies that can be deformed elastically. The `addSpring` method allows users to define new springs with specific stiffnesses and damping factors, while the `addForce` and `addDForce` methods compute forces and their derivatives for simulation purposes. The `FrameSpringForceField` is particularly useful in simulating elastic structures or connections between rigid components in a more physically realistic manner.
{
  "name": "FrameSpringForceField",
  "main": {
    "name": "FrameSpringForceField",
    "namespace": "sofa::component::solidmechanics::spring",
    "module": "Sofa.Component.SolidMechanics.Spring",
    "include": "sofa/component/solidmechanics/spring/FrameSpringForceField.h",
    "doc": "Springs for Flexibles.\n\nFrameSpringForceField simulates 6D springs between moving frames\n        Use stiffnessTrans vector to specify the directionnal stiffnesses (on each local axis)\n        Use stiffnessRot vector to specify the rotational stiffnesses (on each local axis)",
    "inherits": [
      "PairInteractionForceField"
    ],
    "templates": [
      "sofa::defaulttype::Rigid3Types"
    ],
    "data_fields": [
      {
        "name": "d_showLawfulTorsion",
        "type": "bool",
        "xmlname": "showLawfulTorsion",
        "help": "display the lawful part of the joint rotation"
      },
      {
        "name": "d_showExtraTorsion",
        "type": "bool",
        "xmlname": "showExtraTorsion",
        "help": "display the illicit part of the joint rotation"
      },
      {
        "name": "data",
        "type": "DataTypes"
      }
    ],
    "links": [],
    "methods": [
      {
        "name": "addSpringForce",
        "return_type": "void",
        "params": [
          {
            "name": "potentialEnergy",
            "type": "SReal &"
          },
          {
            "name": "f1",
            "type": "VecDeriv &"
          },
          {
            "name": "p1",
            "type": "const VecCoord &"
          },
          {
            "name": "v1",
            "type": "const VecDeriv &"
          },
          {
            "name": "f2",
            "type": "VecDeriv &"
          },
          {
            "name": "p2",
            "type": "const VecCoord &"
          },
          {
            "name": "v2",
            "type": "const VecDeriv &"
          },
          {
            "name": "i",
            "type": "int"
          },
          {
            "name": "spring",
            "type": "const Spring &"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "protected"
      },
      {
        "name": "addSpringDForce",
        "return_type": "void",
        "params": [
          {
            "name": "df1",
            "type": "VecDeriv &"
          },
          {
            "name": "dx1",
            "type": "const VecDeriv &"
          },
          {
            "name": "df2",
            "type": "VecDeriv &"
          },
          {
            "name": "dx2",
            "type": "const VecDeriv &"
          },
          {
            "name": "i",
            "type": "int"
          },
          {
            "name": "spring",
            "type": "const Spring &"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "protected"
      },
      {
        "name": "getObject1",
        "return_type": "core::behavior::MechanicalState<DataTypes> *",
        "params": [],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "getObject2",
        "return_type": "core::behavior::MechanicalState<DataTypes> *",
        "params": [],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "init",
        "return_type": "void",
        "params": [],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "addForce",
        "return_type": "void",
        "params": [
          {
            "name": "mparams",
            "type": "const core::MechanicalParams *"
          },
          {
            "name": "data_f1",
            "type": "DataVecDeriv &"
          },
          {
            "name": "data_f2",
            "type": "DataVecDeriv &"
          },
          {
            "name": "data_x1",
            "type": "const DataVecCoord &"
          },
          {
            "name": "data_x2",
            "type": "const DataVecCoord &"
          },
          {
            "name": "data_v1",
            "type": "const DataVecDeriv &"
          },
          {
            "name": "data_v2",
            "type": "const DataVecDeriv &"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "addDForce",
        "return_type": "void",
        "params": [
          {
            "name": "mparams",
            "type": "const core::MechanicalParams *"
          },
          {
            "name": "data_df1",
            "type": "DataVecDeriv &"
          },
          {
            "name": "data_df2",
            "type": "DataVecDeriv &"
          },
          {
            "name": "data_dx1",
            "type": "const DataVecDeriv &"
          },
          {
            "name": "data_dx2",
            "type": "const DataVecDeriv &"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "buildDampingMatrix",
        "return_type": "void",
        "params": [
          {
            "name": "",
            "type": "core::behavior::DampingMatrix *"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "getPotentialEnergy",
        "return_type": "SReal",
        "params": [
          {
            "name": "",
            "type": "const core::MechanicalParams *"
          },
          {
            "name": "",
            "type": "const DataVecCoord &"
          },
          {
            "name": "",
            "type": "const DataVecCoord &"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "getSprings",
        "return_type": "int *",
        "params": [],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "draw",
        "return_type": "void",
        "params": [
          {
            "name": "vparams",
            "type": "const core::visual::VisualParams *"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "clear",
        "return_type": "void",
        "params": [
          {
            "name": "reserve",
            "type": "int"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "addSpring",
        "return_type": "void",
        "params": [
          {
            "name": "s",
            "type": "const Spring &"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "addSpring",
        "return_type": "void",
        "params": [
          {
            "name": "m1",
            "type": "int"
          },
          {
            "name": "m2",
            "type": "int"
          },
          {
            "name": "softKst",
            "type": "Real"
          },
          {
            "name": "softKsr",
            "type": "Real"
          },
          {
            "name": "kd",
            "type": "Real"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      }
    ]
  },
  "desc": {
    "description": "The `FrameSpringForceField` is a SOFA (Simulation Open-Framework Architecture) component that simulates 6D springs between moving frames, typically used in rigid body dynamics simulations.",
    "parameters": [
      {
        "name": "`d_springs`",
        "type": "sofa::type::vector<Spring>",
        "description": "A list of spring objects. Each Spring object holds information about a specific spring including the indices of the two extremities (m1 and m2), stiffness for translation (`stiffnessTrans`) and rotation (`stiffnessRot`), damping factor (`kd`), initial vectors vec1 and vec2 that define the orientation in space."
      },
      {
        "name": "`d_showLawfulTorsion`",
        "type": "Data<bool>",
        "description": "A boolean to allow the display of the lawful part (expected behavior) of torsions in the spring joints. This can be useful for visual debugging purposes."
      },
      {
        "name": "`d_showExtraTorsion`",
        "type": "Data<bool>",
        "description": "A boolean to display the extra or illicit parts of the joint rotations that go beyond what is allowed by the defined constraints. Again, useful for debugging and understanding the behavior of joints."
      }
    ],
    "methods": [
      {
        "name": "`init()`",
        "description": "Initializes the `FrameSpringForceField` component. Typically sets up necessary variables or performs any required setup."
      },
      {
        "name": "`addForce(...)`",
        "description": "Calculates and adds forces on the mechanical model according to spring properties, current positions, velocities of objects connected by springs. This method updates the force fields `f1` and `f2` based on the specified MechanicalParams."
      },
      {
        "name": "`addDForce(...)`",
        "description": "Applies stiffness by accumulating changes in forces (`df`) given changes in positions (`dx`). It implements how the system responds to small displacements, which is crucial for solving the mechanical equations of motion."
      },
      {
        "name": "`buildDampingMatrix(...)`",
        "description": "Sets up or updates the damping matrix. Damping accounts for energy loss due to friction and other dissipative forces in a physical simulation. This function is called during system setup or whenever damping parameters change."
      },
      {
        "name": "`getPotentialEnergy(...)`",
        "description": "Calculates the potential energy of the mechanical model associated with the current configuration of springs. The result depends on the stiffness and displacements from rest positions."
      },
      {
        "name": "`draw(...)`",
        "description": "Renders visual representation of the `FrameSpringForceField`, including the position, orientation and possible states (like lawful vs extra torsion) of its components for visual debugging or presentation purposes."
      }
    ],
    "interaction_methods": [
      {
        "name": "`addSpring(...)`",
        "description": "Adds a new spring to the system with specified parameters like indices of connected rigid bodies (`m1`, `m2`), stiffness, damping coefficient and initial vectors defining orientation. This method allows dynamic addition of constraints during simulation setup or runtime."
      },
      {
        "name": "`clear()`",
        "description": "Removes all springs from the system. Optionally, reserves space in the internal vector to hold a specific number of spring objects (default: 0). Useful for resetting the system before reconfiguration."
      }
    ],
    "notes": [
      "The `FrameSpringForceField` class is specialized for use with rigid body types (`Rigid3Types`). It inherits from `PairInteractionForceField`, indicating that it models interactions between pairs of mechanical systems. The component uses internal data structures to store references and intermediate computations, aiding in efficient force calculations."
    ],
    "examples_of_use": [
      "This component can be used to model flexible connectors or constraints within a robotic arm simulation where each segment is represented as a rigid body, allowing for realistic movement and collision responses.",
      "In biomechanics simulations, it can simulate ligaments connecting bones with specific stiffness properties that affect the overall motion."
    ],
    "dependencies": [
      "SOFA core",
      "behavior module",
      "visual module"
    ]
  },
  "maths": {
    "maths": "## Mathematical and Physical Description of FrameSpringForceField\n\nThe `FrameSpringForceField` in the SOFA framework simulates springs between moving frames (rigid bodies) with six degrees of freedom (DOF), including three translational and three rotational DOFs. This component is used to model elastic interactions in rigid body simulations.\n\n### Springs Between Moving Frames\n\nEach spring connects two rigid bodies (or frames) at specific points, defined by the indices `m1` and `m2`. The stiffness parameters for each spring are `stiffnessTrans`, which affects the translational degrees of freedom, and `stiffnessRot`, which affects the rotational degrees of freedom. Additionally, a damping factor `kd` can be applied to dissipate energy in the system.\n\n### Force Calculation\n\nThe force and torque exerted by each spring on the connected rigid bodies is calculated based on their current positions and orientations relative to their initial configuration. The force due to translational deformation is computed using:\n\n$$\n\\mathbf{F}_{trans} = -k_{st}(\\mathbf{x}_1 + \\vec{r_1} - (\\mathbf{x}_2 + \\vec{r_2}))\n$$\n\nwhere $\\mathbf{x}_1$ and $\\mathbf{x}_2$ are the positions of the rigid bodies, $\\vec{r_1}$ and $\\vec{r_2}$ are vectors along the translational DOFs from the body's center to the spring attachment points, and $k_{st}$ is the stiffnessTrans parameter.\n\nThe torque due to rotational deformation is calculated using:\n\n$$\n\\mathbf{T}_{rot} = -k_{sr}(\\mathbf{R}_1 \\cdot \\vec{v_1} - (\\mathbf{R}_2 \\cdot \\vec{v_2}))\n$$\n\nwhere $\\mathbf{R}_1$ and $\\mathbf{R}_2$ are rotation matrices representing the orientations of the rigid bodies, $\\vec{v_1}$ and $\\vec{v_2}$ are vectors along the rotational DOFs from the body's center to the spring attachment points, and $k_{sr}$ is the stiffnessRot parameter.\n\n### Damping\n\nDamping force/torque due to velocity differences can be added as follows:\n\n$$\n\\mathbf{F}_{damp} = -kd(\\dot{\\mathbf{x}}_1 + \\vec{r_1} - (\\dot{\\mathbf{x}}_2 + \\vec{r_2})) \\\\\n\\mathbf{T}_{damp} = -kd(\\dot{\\mathbf{R}}_1 \\cdot \\vec{v_1} - (\\dot{\\mathbf{R}}_2 \\cdot \\vec{v_2}))\n$$\n\n### Potential Energy\n\nThe potential energy stored in the spring is given by:\n\n$$\nU = \\frac{1}{2}k_{st}|(\\mathbf{x}_1 + \\vec{r_1}) - (\\mathbf{x}_2 + \\vec{r_2})|^2 + \\frac{1}{2}k_{sr}|(\\mathbf{R}_1 \\cdot \\vec{v_1}) - (\\mathbf{R}_2 \\cdot \\vec{v_2})|^2\n$$\n\n### Application in SOFA\n\nIn the SOFA framework, this component is used to create physical interactions between rigid bodies that can be deformed elastically. The `addSpring` method allows users to define new springs with specific stiffnesses and damping factors, while the `addForce` and `addDForce` methods compute forces and their derivatives for simulation purposes.\n\nThe `FrameSpringForceField` is particularly useful in simulating elastic structures or connections between rigid components in a more physically realistic manner."
  },
  "summary": {
    "abstract": "The `FrameSpringForceField` simulates 6D springs between rigid bodies with parameters for translational and rotational stiffness and damping. It computes forces and torques based on the deformation of connected frames.",
    "sheet": "# FrameSpringForceField\n\n## Overview\n\nThe `FrameSpringForceField` is a component in SOFA that simulates 6D springs (three translational and three rotational degrees of freedom) between rigid bodies. This component inherits from `PairInteractionForceField` and is used to model elastic interactions in rigid body dynamics simulations.\n\n## Mathematical Model\n\nEach spring connects two rigid bodies at specific points, defined by indices `m1` and `m2`. The stiffness parameters for each spring are `stiffnessTrans`, which affects the translational degrees of freedom, and `stiffnessRot`, which affects the rotational degrees of freedom. Additionally, a damping factor `kd` can be applied to dissipate energy in the system.\n\n### Force Calculation\n\nThe force due to translational deformation is computed using:\n\n\begin{equation}\n\\mathbf{F}_{trans} = -k_{st}(\\mathbf{x}_1 + \\vec{r_1} - (\\mathbf{x}_2 + \\vec{r_2}))\n\\end{equation}\n\nwhere $\\mathbf{x}_1$ and $\\mathbf{x}_2$ are the positions of the rigid bodies, $\\vec{r_1}$ and $\\vec{r_2}$ are vectors along the translational DOFs from the body's center to the spring attachment points, and $k_{st}$ is the stiffnessTrans parameter.\n\nThe torque due to rotational deformation is calculated using:\n\n\begin{equation}\n\\mathbf{T}_{rot} = -k_{sr}(\\mathbf{R}_1 \\cdot \\vec{v_1} - (\\mathbf{R}_2 \\cdot \\vec{v_2}))\n\\end{equation}\n\nwhere $\\mathbf{R}_1$ and $\\mathbf{R}_2$ are rotation matrices representing the orientations of the rigid bodies, $\\vec{v_1}$ and $\\vec{v_2}$ are vectors along the rotational DOFs from the body's center to the spring attachment points, and $k_{sr}$ is the stiffnessRot parameter.\n\n### Damping\n\nDamping force/torque due to velocity differences can be added as follows:\n\n\begin{equation}\n\\mathbf{F}_{damp} = -kd(\\dot{\\mathbf{x}}_1 + \\vec{r_1} - (\\dot{\\mathbf{x}}_2 + \\vec{r_2})) \\\\\n\\mathbf{T}_{damp} = -kd(\\dot{\\mathbf{R}}_1 \\cdot \\vec{v_1} - (\\dot{\\mathbf{R}}_2 \\cdot \\vec{v_2}))\n\\end{equation}\n\n### Potential Energy\n\nThe potential energy stored in the spring is given by:\n\n\begin{equation}\nU = \\frac{1}{2}k_{st}|(\\mathbf{x}_1 + \\vec{r_1}) - (\\mathbf{x}_2 + \\vec{r_2})|^2 + \\frac{1}{2}k_{sr}|(\\mathbf{R}_1 \\cdot \\vec{v_1}) - (\\mathbf{R}_2 \\cdot \\vec{v_2})|^2\n\\end{equation}\n\n## Practical Notes\n\nThe `FrameSpringForceField` is particularly useful in simulating elastic structures or connections between rigid components. Care should be taken to ensure that the stiffness and damping parameters are chosen appropriately for numerical stability."
  }
}