1. Algorithm description
PDR (Pedestrian Dead Reckoning) library allows to estimate the trajectories travelled by a user during a self-paced walking movement. PDR is a IMU-based solution that exploits only linear accelerations, angular velocity readings and magnetic field variation readings, measured in mg, dps and mG, respectively and sampled @100Hz. PDR requires a single inertial sensor, that can be installed on 4 different positions on the user’s foot (i.e., foot instep, heel, external ankle, internal ankle). It is worth noting that such a position is automatically detected on movement start.
PDR integration requires only 3 lines of code, which implement the following functionalities:
-
PDR_Init. It must be invoked before running the logic. It allows to set all the configuration parameters and
internal variables. -
PDR_Update. It runs the following core functions of the logic, as depicted in the AlgorithmFlowchart.
- Motion Processing. It computes sensor orientation estimation and other functionalities used to track the foot motion;
- Reset Condition. It aligns data from local sensor to user reference system. At the current solution, automatic compensation is carried out exploiting first steps and compensating for the detected sensor positioning on the foot;
- Activity Tracking. It tracks user activities. Following types of activities are labelled: static condition, dynamic condition of generic type, walking activity and running activity;
- Step Counter. It counts user’s steps;
- Trajectory Estimation. It that provides planar coordinates and overall trajectory length in meters units;
- Other Custom Metrics are available for development on demand
- PDR_Get_Output. It returns the tracking metrics output values.
Note: Magnetometer data is not mandatory for the functioning of PDR library; therefore, the proposed solution can be both 6DOF and 9DOF. The introduction of magnetic field readings may prevent trajectory from drifting in some situations (e.g., when the ground is rough).
2. Flowchart
The following block diagram describes the flow of operations that implement the PDR logic.
FIGURE2.1 ALGORITHM FLOWCHART
3. References
The following block diagram describes the flow of operations that implement the PDR logic.
The following lines contain general information about the library, such as version and date of publication, together with the contact details of the 221e internal staff responsible for maintaining and managing the library.
-
Authors and Referents
Giorgio Barzon
Luigi Mattiello
Roberto Bortoletto -
Library Version
v2.0.0 -
Date
July 2022 -
Copyright
Copyright (c) 2020 All Rights Reserved by 221e srl. [email protected]
4. Requirements
The following lines contain information about the library size occupation and time execution. Tests and measurements have been perfomed with a NUCLEO-F401RE board, clocked @64MHz, and including within Atollic TrueSTUDIO project the PDR static library compiled for NUCLEO-F401RE as well as library header files. No optimization (i.e., -O0) has been applied during library compilation. Results are reported in the following tables.
FLASH Occupation [kB] | RAM Occupation [kB] |
---|---|
49.08 | 6.71 |
TABLE 4.1 PDR MEMORY OCCUPATION
Timing [clock hits] | Timing @64MHz [ms] | |
---|---|---|
PDR_Update in dynamic phase |
Average: 48235, Maximum: 70750 | Average: 0.754, Maximum: 1.105 |
PDR_Update at step detection | Average: 128962, Maximum: 160989 | Average: 2.015, Maximum: 2.515 |
PDR_Init |
Average: 18756, Maximum: 18798 | Average: 0.293, Maximum: 0.294 |
TABLE 4.1 PDR EXECUTION TIMINGS
Greater time values of PDR_Update execution occurs when a single step is completed.
5. Example Documentation
10.1 PDR_Example.c
This is an example of library usage for PDR logic, based on accelerometer and gyroscope data, where:
- A proper initialization of PDR algorithm is shown
- Streaming of data is simulated by reading from a .txt file
- A correct call to PDR_Update function is shown
#include <stdio.h> // Include C standard libraries #include <stdint.h> #include <stdbool.h> #include <math.h> #include "PDR_Tracker.h" // Include PDR_Tracker.h library #define inputDataLength 9 // Define input data lenght float inputData[inputDataLength] = {0,0,0,0,0,0,0,0,0}; // Initialize input data array: Gyr [dps], Axl [mg] and Mag[mG] triplets PDR_TypeDef PDR_out; // Define PDR outupt struct // Main function int main(void){ uint8_t i; // Support variable FILE *fIn = fopen("input_file.txt", "r"); // Open input file FILE *fOut = fopen("output_file.txt", "w"); // Open output file PDR_Init(); // PDR_Init call PDR_InitInertialData(PDR_inputData); // Init of variable where to store input data //While loop while (feof(fIn) == 0) { // Read current data for (i = 0; i < inputDataLength; i++) fscanf(fIn, "%f", &inputData[i]); // Read data: Gyr.X Gyr.Y Gyr.Z Acc.X Acc.Y Acc.Z Mag.X Mag.Y Mag.Z PDR_inputData.Gyr[0] = inputData[0]; PDR_inputData.Gyr[1] = inputData[1]; PDR_inputData.Gyr[2] = inputData[2]; PDR_inputData.Axl[0] = inputData[3]; PDR_inputData.Axl[1] = inputData[4]; PDR_inputData.Axl[2] = inputData[5]; PDR_inputData.Mag[0] = inputData[6]; PDR_inputData.Mag[1] = inputData[7]; PDR_inputData.Mag[2] = inputData[8]; PDR_Update(PDR_inputData); // PDR_Update call PDR_out = PDR_Get_Output(); // PDR_Get_Output call fprintf(fOut, "%dnt", PDR_out.Activity); // Print Activity Type result on output file fprintf(fOut, "%dnt", PDR_out.Steps); // Print number of steps on output file fprintf(fOut, "%fnt", PDR_out.Trajectory[0]); // Print x-direction trajectory on output file fprintf(fOut, "%fnt", PDR_out.Trajectory[1]); // Print y-direction trajectory on output file fprintf(fOut, "%fnn", PDR_out.Trajectory[2]); // Print trajectory length on output file } // Close I/O files fclose(fIn); fclose(fOut); return 0; }
10.2 Visualization
A visual representation of the results is shown in the following figure ExampleFigure, where the results of a walk around an approximately 120 meters long rectangular path are shown. The data were acquired with the 221e Muse device, installed on the user instep.
FIGURE 10.1 OUTPUT EXAMPLE