This is a public Edge Impulse project, use the navigation bar to see all data and models in this project; or clone to retrain or deploy to any edge device.
MATLAB: Synthetic Data Generation - Continuous motion recognition
MATLAB: Synthetic Data Generation - Continuous motion recognition
About this project
how to generate synthetic accelerometer motion data in matlab for edge impulse
introduction
this tutorial guides you through generating synthetic accelerometer motion data in matlab for use with edge impulse. it is inspired by the continuous motion recognition dataset created by edge impulse, which was collected using a mems accelerometer at 62.5hz. this dataset is commonly used for motion and vibration classification tasks, particularly in gesture recognition and industrial monitoring applications.
background
the original dataset includes four distinct motion types:
- idle: the device remains stationary with minimal movement, similar to being placed on a desk.
- snake: the device moves in a wave-like motion across a surface.
- updown: the device moves vertically in
Build your own version of this dataset at https://matlab.mathworks.com/
Launch the following script within MATLAB live code
Alternativly copy this script into your own local MATLAB instance
%% Clear Workspace and Define Sampling Parameters % This section clears any previous variables and defines sampling settings.
clear; clc;
fs = 62.5; % Sampling frequency (Hz) t_end = 5 * 60; % Total duration in seconds t = 0:1/fs:t_end-1/fs; % Time vector N = length(t); num_samples = 101;
target_freq = 0.5; % 0.5 Hz = 5 cycles per 10 seconds
%% Generate Motion Signals % Different types of motion signals are generated with noise and jitter to % mimic real-world sensor variations.
jitter = 0.1 randn(size(t)); variable_freq = target_freq + 0.05 sin(2 pi 0.01 * t);
% Idle motion (minimal noise, near zero variation) idle_x = 0.00001 randn(size(t)); idle_y = 0.00001 randn(size(t)); idle_z = 0.00001 * randn(size(t));
% Up-down motion (vertical oscillation with randomness) updown_x = zeros(size(t)); updown_y = zeros(size(t)); updown_z = 0.8 sin(2 pi variable_freq . t) + jitter;
% Snake motion (horizontal oscillation with amplitude modulation) snake_x = (0.7 + 0.2 sin(2 pi 0.005 t)) . sin(2 pi variable_freq . t) + jitter; snake_y = zeros(size(t)); snake_z = zeros(size(t));
% Wave motion (circular oscillation with speed variation) wave_x = (0.6 + 0.1 cos(2 pi 0.003 t)) . cos(2 pi variable_freq . t) + jitter; wave_y = (0.6 + 0.1 cos(2 pi 0.003 t)) . sin(2 pi variable_freq . t) + jitter; wave_z = zeros(size(t));
%% Add Noise and Environmental Variations % Introduce small random noise to simulate sensor imperfections.
global_noise_level = 0.00005; temp_variation = 0.00002 sin(2 pi 0.1 t); vibration_noise = 0.00008 * randn(size(t));
idle_x = idle_x + temp_variation; idle_y = idle_y + vibration_noise; idle_z = idle_z + temp_variation;
updown_z = updown_z + global_noise_level randn(size(t)) + temp_variation; snake_x = snake_x + global_noise_level randn(size(t)); snake_y = snake_y + global_noise_level randn(size(t)) + vibration_noise; wave_x = wave_x + global_noise_level randn(size(t)) + temp_variation; wave_y = wave_y + global_noise_level * randn(size(t)) + vibration_noise;
%% Create Labeled Dataset % Assign each motion type to a category and prepare the dataset.
labels = {"idle", "snake", "updown", "wave"}; combined_data = [];
for k = 1:num_samples motion_index = mod(k-1, 4) + 1; label = labels{motion_index}; switch label case "idle" acc_x = idle_x; acc_y = idle_y; acc_z = idle_z; case "snake" acc_x = snake_x; acc_y = snake_y; acc_z = snake_z; case "updown" acc_x = updown_x; acc_y = updown_y; acc_z = updown_z; case "wave" acc_x = wave_x; acc_y = wave_y; acc_z = wave_z; end
label_column = repmat(label, length(t), 1);
motion_data = [t', acc_x', acc_y', acc_z', string(label_column)];
combined_data = [combined_data; motion_data];
end
%% Save Dataset to CSV File % Store the generated data into a CSV file.
csv_filename = 'motion_data.csv'; writematrix(combined_data, csv_filename);
disp(['Dataset saved as ', csv_filename]);
%% Plot Motion Signals % Visualizing the generated motion signals for each category.
motion_signals = {idle_x, snake_x, updown_x, wave_x; ... idle_y, snake_y, updown_y, wave_y; ... idle_z, snake_z, updown_z, wave_z};
colors = {'r', 'g', 'c'}; % Red for X, Green for Y, Cyan for Z figure;
for i = 1:length(labels) subplot(2,2,i); hold on; for j = 1:3 plot(t*1000, motion_signals{j,i}, 'Color', colors{j}, 'LineWidth', 1.5); end hold off; title(sprintf('Motion: %s', labels{i}), 'fontsize', 12); xlabel('Time (ms)', 'fontsize', 10); ylabel('Acceleration', 'fontsize', 10); xlim([0, 10000]); legend({'accX', 'accY', 'accZ'}, 'location', 'best'); grid on; end
%% Add Interactive Buttons % These buttons allow users to run the script and download the dataset.
uicontrol('Style', 'pushbutton', 'String', 'Run Simulation', ... 'Position', [20 20 120 40], 'FontSize', 12, ... 'Callback', @(~,~) evalin('base', 'run(mfilename)'));
uicontrol('Style', 'pushbutton', 'String', 'Download CSV', ... 'Position', [160 20 120 40], 'FontSize', 12, ... 'Callback', @(~,~) web(['file://', fullfile(pwd, csv_filename)], '-browser'));
Run this model
Dataset summary
Data collected
8h 25m 0sSensors
acc_x, acc_y, acc_z @ 62.5HzLabels
idle, snake, updown, waveProject info
Project ID | 644046 |
License | BSD 3-Clause Clear |
No. of views | 4,860 |
No. of clones | 1 |