Eoin / MATLAB: Synthetic Data Generation - Continuous motion recognition Public

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'));

motion_data (1).s2250
motion_data (1).s20
motion_data (1).s2176
motion_data (1).s2785
motion_data (1).s1117
motion_data (1).s684
motion_data (1).s2390
motion_data (1).s638

Run this model

On any device

Dataset summary

Data collected
8h 25m 0s
Sensors
acc_x, acc_y, acc_z @ 62.5Hz
Labels
idle, snake, updown, wave

Project info

Project ID 644046
License BSD 3-Clause Clear
No. of views 4,860
No. of clones 1