Skip to main content

Tutorial 1 – Joint Model Personalization

Tutorial Developers: Robert Salati, B.J. Fregly, Rice Computational Neuromechanics Lab, Rice University

Last Updated: 11/4/2025

The Joint Model Personalization (JMP) tool optimizes joint parameters, body scaling, and marker placement to minimize IK marker distance errors. Reducing inverse kinematics marker distance errors reduces downstream errors in calculated inverse dynamic joint moments, muscle–tendon lengths and velocities, muscle moment arms, and ultimately muscle activations and forces. These quantities are used by subsequent Model Personalization tools.

The inputs to JMP are a scaled generic OpenSim model, kinematic marker data from one or more motion trials, and a JMP settings file. This tutorial will explore the creation of JMP settings file using both the NMSM Pipeline GUI in OpenSim, and by directly editing the settings file in a text editor.

Before running JMP:

The primary input to a JMP run is a scaled generic OpenSim model. JMP is designed for small adjustments to model parameters, so large scaling adjustments should still be done with OpenSim’s Scale Model Tool.

  1. Open RCNL2023.osim in the OpenSim GUI.
  2. Open the Scale Model Tool.
  3. Load the settings file ScaleSettings.xml.
  4. Run the scale tool
  5. With the new model UF_Subject_3_v2.osim selected in the Navigator window, click on the Coordinates window.
  6. Lock knee_adduction_r and knee_adduction_l a. The knee adduction angle models varus/valgus deformity and doesn’t change much during gait. The scale tool modifies this angle using static pose data, and then we don’t change it afterwards.
  7. Save the scaled model as UF_Subject_3_scaled.osim.

To get the most accurate personalization, JMP prefers that “functional joint trials” are used, in which a single joint is moved through its full range of motion. We can visualize these motions using the OpenSim Inverse Kinematics Tool.

  1. With UF_Subject_3_scaled.osim selected in the OpenSim GUI, open the Inverse Kinematics Tool.
  2. Load the IK settings files inside IKSettingsFiles
  3. Run the settings files to visualize the motion trials available to us in this tutorial.

Setting up a JMP settings file:

  1. Activate the NMSM GUI in OpenSim by navigating to Tools>User Plugins, and click rcnlPlugin.dll

  2. Open UF_Subject_3_scaled.osim in the OpenSim GUI

  3. With UF_Subject_3_scaled.osim selected in the OpenSim GUI, navigate to Tools>Model Personalization>Joint Model Personalization

    a. The following window should be opened:

    image

  4. Rename the output model file to UF_Subject_3_scaled_Sequential.osim

  5. Create a new JMP Task:

    a. Name this task Scale Pelvis

    b. Select the Markers File to be MarkerFiles\BothHips_markers.trc

    c. Choose the Markers to be R_Thigh_Lateral R_Thigh_Superior R_Thigh_Inferior L_Thigh_Lateral L_Thigh_Superior L_Thigh_Inferior R_Asis L_Asis Sacral

    d. Add a new body to this task:

    - Body name: Pelvis
    - Scale body: Yes
    - Move markers: None
  6. Create a new JMP Task:

    a. Name this task Right Knee

    b. Select the Markers File to be MarkerFiles\RightKnee_markers.trc

    c. Choose the Markers to be R_Thigh_Lateral R_Thigh_Superior R_Thigh_Inferior R_Shank_Superior R_Shank_Inferior R_Shank_Lateral

    d. Add a new joint to this task.

    - Joint name: knee_r
    - Parent frame translation: None
    - Parent frame rotation: X-, Y- axes
    - Child frame translation: None
    - Child frame rotation: X-, Y- axes
  7. Create a new JMP Task:

    a. Name this task Right Ankle

    b. Select the Markers File to be MarkerFiles\RightAnkle_markers.trc

    c. Choose the Markers to be R_Shank_Superior R_Shank_Inferior R_Shank_Lateral R_Heel R_Midfoot_Superior R_Midfoot_Lateral

    d. Add a new joint to this task.

    - Joint name: ankle_r
    - Parent frame translation: None
    - Parent frame rotation: X-, Y- axes
    - Child frame translation: None
    - Child frame rotation: None

    e. Add a new joint to this task.

    - Joint name: subtalar_r
    - Parent frame translation: None
    - Parent frame rotation: Y-, Z- axes
    - Child frame translation: None
    - Child frame rotation: Y-, Z- axes
  8. Save the settings file as JMPSettingsSequential.xml

  9. Open JMPSettingsSequential.xml in a text editor, and explore the document

Running JMP:

  1. Open MATLAB and open runJMP.m in your tutorial directory.

  2. Open the project file Project.prj inside your installation of nmsm-core.

  3. Ensure MATLAB is set up to use multi-processing, not multi-threading:

    a. In the bottom left of MATLAB, click the parallel processing icon, and click parallel preferences.

    b. In the drop down menu for Default Profile, select Processes.

  4. Run the MATLAB section labelled Run JMP Sequential

    a. With the section selected, press shift+enter to run a section.

Experiment with simultaneous JMP runs:

The previous JMP run personalized all joints sequentially from the ankle upwards. This has the benefit of a quicker runtime but has more error because the personalization of one joint can negatively affect the personalization of another joint. This can be addressed by personalizing all joints simultaneously. Simultaneous JMP runs take much longer to run but have lower error at the end.

To set up a simultaneous JMP run, you need to normalize all marker trials to 101 time points, and concatenate all of them together into one file. This has already been done in MarkerFiles\ AnkleKneeGaitConcatenated_markers.trc.

  1. With UF_Subject_3_scaled.osim selected in the OpenSim GUI, open a new JMP GUI window.

    a. This allows us to use the previous JMP run as a starting point for a new JMP run.

  2. Rename the output model file to UF_Subject_3_scaled_Simultaneous.osim

  3. Create a new JMP Task:

    a. Name this task All Joints

    b. Select the Markers File to be MarkerFiles\ AnkleKneeHipsGaitConcatenated_markers.trc

    c. Choose the markers to be R_Asis L_Asis Sacral R_Thigh_Lateral R_Thigh_Superior R_Thigh_Inferior L_Thigh_Lateral L_Thigh_Superior L_Thigh_Inferior R_Shank_Superior R_Shank_Inferior R_Shank_Lateral R_Heel R_Midfoot_Superior R_Midfoot_Lateral

    d. Add a new joint to this task.

    - Joint name: ankle_r
    - Parent frame translation: None
    - Parent frame rotation: X-, Y- axes
    - Child frame translation: None
    - Child frame rotation: None

    e. Add a new joint to this task.

    - Joint name: subtalar_r
    - Parent frame translation: None
    - Parent frame rotation: Y-, Z- axes
    - Child frame translation: None
    - Child frame rotation: Y-, Z- axes

    f. Add a new joint to this task.

    - Joint name: knee_r
    - Parent frame translation: None
    - Parent frame rotation: X-, Y- axes
    - Child frame translation: None
    - Child frame rotation: X-, Y- axes

    g. Add a new body to this task:

    - Body name: Pelvis
    - Scale body: Yes
    - Move markers: None

    h. Add a new body to this task:

    - Body name: femur_r
    - Scale body: No
    - Move markers: X-, Y- axes

    i. Add a new body to this task:

    - Body name: tibia_r
    - Scale body: No
    - Move markers: X-, Y-axes
  4. Save this settings file as JMPSettingsSimultaneous.xml

  5. Open JMPSettingsSimultaneous.xml in a text editor of your choice.

  6. This JMP run can take quite long to run, so premade results are in CompletedSettingsFiles

Questions:

  1. In 1-2 sentences, explain how the JMP optimization works.

  2. Why do we prefer functional trials over gait trials? What if we only had gait trials? What joints should we personalize then? Are there any joints we shouldn’t personalize if we only have gait trials? What about other motions such as squatting?

  3. When JMP changes joint or body parameters, it does not automatically move markers unless specifically instructed to. Why would you not want to move markers when personalizing joint axes and scaling bodies?

  4. If JMP has capabilities to scale bodies, why is it recommended to start with a scaled generic model instead of scaling the model entirely with JMP?

  5. The first part of this tutorial used a “sequential” approach to JMP, where each joint is personalized sequentially in its own task. The main benefit of this approach is that sequential JMP runs are computationally faster because the inverse kinematics problem is simpler. What are some drawbacks of the sequential approach?

  6. What are the potential benefits and drawbacks of a simultaneous JMP approach?

  7. Was the calibration for the simultaneous JMP run better or worse than the sequential JMP run?