To use OpenSense in Python, you must install OpenSim version 4.1 and then follow the Python scripting setup instructions.
Command Line Setup (TODO: Make sure this is all up-to-date and possibly link to
separate page in the documentation)
Your OpenSim download includes a command line executable that can run all of the OpenSense tools. After you have installed OpenSense, you need to tell your system where to find the OpenSense tools by adding it to your system's path.
The flowchart below shows the workflow for the example (TODO: Update this flowchart). We will import the IMU sensor data, calibrate our OpenSim model, compute inverse kinematics, and then visualize the results.
The first step is to collect your data and convert it into OpenSim formata format that you can read into OpenSim and process with the OpenSense workflow. You must place the sensors on your subject, typically with one sensor per tracked segment. You then must collect calibration data, where the subject is in a known pose, followed by the movement of interest (e.g., gait). For each IMU sensor, you must keep track of which sensor is placed on which body. You must also keep track of the timestamp(s) for the calibration pose.
In our example, the calibration pose is a neutral pose where the hips, knees, and ankles were at (or close) to 0 degrees.
TODO: Add details about base IMU and its direction .... folks will also need to keep track of this.
IMU sensor systems, like Xsens and APDM, typically provide features that perform sensor fusion, time syncing, and data interpolation for missing entries. The current version of OpenSense assumes that this pre-processing has already been performed and that you are inputting processed rotation matrices.
Each IMU sensor is represented as a Frame in an OpenSim Model, where a Frame is an orthogonal XYZ coordinate system. When you read in your data, OpenSense will find the appropriate IMU frame in your model (based on the mappings XML file) or create an IMU Frame, if it doesn't already exist. OpenSense uses a naming convention where we expect the sensor to be named as <bodyname>_imu. For example, the OpenSim model has a right femur body called femur_r, therefore the IMU sensor must be called femur_r_imu.
The IMU reader then creates a storage file with the orientation data for each sensor, where each column in the storage file is named according to the frame in the corresponding OpenSim model.
Matlab commands to create an orientations file from IMU sensor data
>> import org.opensim.modeling.*; // Import the OpenSim modeling commands >>
Python commands to create an orientations file from IMU sensor data
Command-line tool to create an orientations file from IMU sensor data
To read your data into OpenSim from the command line, use the following steps.
The OpenSense Calibration step takes an OpenSim Model and the IMU calibration data and finds the initial orientations of the IMU Frames (i.e. offsets) relative to the OpenSim body segments. We provide a basic algorithm for calibration or you can also create your own methods of calibration by developing your own algorithms (in C++ or via scripting) to compute a default pose and/or the transforms of the IMU sensors.
To use OpenSense's calibration, you must provide an OpenSim Model in the calibration step. In our example, we are using the Rajagopal (2015) model. As noted above, on data read, either your Model should have IMU frames attached that correspond to the name_in_model specified in Step Two, or if you use our assumed naming convention (<bodyname>_imu), the calibrate step will add IMU Frames to the model as long as there is a corresponding body segment with a matching <bodyname>.
OpenSense calibration assumes that the pose of the subject in the calibration data matches the default pose of the model. In our example, the calibration pose is with the pelvis, hip, knee, and ankle at neutral, so we did not need to make any adjustments to the model's default pose. If you use a different pose, you can edit the pose of the input in the OpenSim GUI, through scripting, or in XML (see Coordinate Controls and Poses to learn how to edit the default pose through the OpenSim GUI).
You must next provide the calibration data. OpenSense assumes the first time point corresponds to the calibration pose. If you have a trial where the calibration pose is performed at some time other than the first time row, you must edit your orientations file (or make a new one) where the first time row best corresponds to the calibration pose.
You can also specify optional arguments that enable OpenSense to correct or adjust for the overall difference in the heading (forward direction) of the IMU data versus that of the OpenSim model. Typically, an OpenSim model is facing in the positive X direction of the ground frame in the initial pose, but the base IMU (e.g., on the pelvis or torso) can have any initial heading. Given the <base_imu_label> (the label that identifies the base IMU in the provided orientation data) and the <base_heading_axis> (the 'x', 'y' or 'z' axis of the base IMU that represents its heading direction), OpenSense will compute the angular offset between the two poses and use it to rotate all the orientation data so that the heading of the base IMU is now directed along the X-axis of the OpenSim ground reference frame (same as the model). If the <base_imu_label> is not provided, then no heading correction is applied. If the <base_imu_label> is provided and no <base_heading_axis> the 'z' axis of the base IMU is assumed to be its heading direction.
The output of the calibration step is a calibrated model, where each IMU is registered to the OpenSim model. The image below shows our example subject with IMU's on the pelvis, trunk, thighs, shanks, and feet segments and the corresponding OpenSim Model with the matching pose.
Matlab commands to calibrate a model in OpenSense
>> myIMUPlacer = IMUPlacer('myIMUPlacer_Setup.xml'); // >> myIMUPlacer.run(true); >> imuPlacer.getCalibratedModel().print('calibrated_Rajagoal_2015.osim')
Command-line tool for calibrating an OpenSim Model