В настоящее время я работаю над проектом, целью которого является интеграция системы захвата движения IMU для обеспечения вибротактильной обратной связи через вибромоторы. Проект ориентирован на бегунов и может быть использован либо для повышения производительности, либо для предотвращения травм. Прямо сейчас я сосредоточен на использовании ИДУ для сбора необходимых параметров, в данном случае — ускорения большеберцовой кости. Я работал над алгоритмом калибровки датчика по сегменту и уже получил некоторые результаты, в достоверности которых я не совсем уверен. Я надеялся, что кто-нибудь сможет дать мне какой-нибудь совет или сказать, если я упускаю что-то важное.
Некоторая актуальная информация:
Я использую датчики Movella Dot, которые уже позволяют определить ориентацию датчика с помощью фильтра Калмана.
Я размещаю датчик в медиальной передней части голени (костной части).
Пока я проведение статической и функциональной калибровки. Где статика — это короткая запись стоя, а функционал — запись медленной ходьбы. При статической калибровке я получаю вертикальную ось, измеряющую вектор гравитации. Из функциональной калибровки я получаю передне-заднюю ось, используя анализ главных компонентов записи ускорения. Наконец, я просто корректирую оси, чтобы обеспечить ортогональность, вычисляю ось Y как векторное произведение, нормализую и, наконец, получаю матрицу преобразования.
Вот что у меня есть на данный момент:
import numpy as np
import pandas as pd
from scipy import signal
from scipy.spatial.transform import Rotation as R
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
# Butterworth filter
def filtering(fs, cutoff, data):
order = 2
b, a = signal.butter(order, (2 * cutoff / fs), btype='low')
filt_data = signal.filtfilt(b, a, data, axis=0)
return filt_data
# Extract accelerometer, gyroscope, and quaternion data
def get_data(filename):
data = pd.read_csv(filename, delimiter=',', header=0)
# Rotate accelerometer data to global frame using quaternions
a_global = np.zeros((N, 3))
for i in range(120, N-1):
q = quaternions # Get quaternion for this sample
a_global[i, :] = rotate_vector(q, acc_data[i, :]) # Rotate using quaternion
# Filter the rotated accelerometer data
a_global_filtered = filtering(fs, 15, a_global)
# Estimate gravity vector during the static upright position
Tstart, Tend = 0, N # Replace with actual indices for static period
gravity_vector = np.mean(a_global_filtered[Tstart:Tend, :], axis=0)
gravity_magnitude = np.linalg.norm(gravity_vector)
sensor_z_axis = gravity_vector
return sensor_z_axis, a_global_filtered, gyr_data
# Functional calibration: Rotate raw data and apply PCA to define X-axis (NOT NORMALIZED)
def functional_calibration(filename):
[acc_data,_, quaternions] = get_data(filename)
fs = 120
N = len(acc_data)
# Rotate accelerometer data to global frame using quaternions
a_global = np.zeros((N, 3))
for i in range(120, N-1):
q = quaternions # Get quaternion for this sample
a_global[i, :] = rotate_vector(q, acc_data[i, :]) # Rotate using quaternion
# Filter the rotated accelerometer data
a_global_filtered = filtering(fs, 15, a_global)
# Now apply PCA to rotated accelerometer data to define the X-axis
scaler = StandardScaler()
a_global_scaled = scaler.fit_transform(a_global_filtered)
# Compute Y-axis to ensure orthogonality and right-handed system
def gram_schmidt(sensor_x_axis, sensor_z_axis):
# Apply Gram-Schmidt process to get orthogonal vectors
sensor_x_axis_corrected = sensor_x_axis - (np.dot(sensor_x_axis, sensor_z_axis)/np.dot(sensor_z_axis, sensor_z_axis)) * sensor_z_axis
# Compute Y-axis as cross product of Z and X to enforce right-handed system
sensor_y_axis = np.cross(sensor_x_axis_corrected, sensor_z_axis)
# Plot raw vs aligned acceleration
fig, axs = plt.subplots(3, 1, figsize=(10, 8))
for i, axis in enumerate(['X', 'Y', 'Z']):
axs.plot(time, a_global[:, i], label=f'Raw {axis}')
axs.plot(time, aligned_acc[:, i], label=f'Aligned {axis}')
axs.set_xlabel('Time (s)')
axs.set_ylabel(f'Acceleration {axis} (m/s^2)')
axs.legend()
axs.grid(True)
plt.tight_layout()
plt.show()
# Calculate and plot PTA (Peak Tibial Acceleration) over time
def plot_pta(aligned_tibia_acc, fs=120):
# Calculate time array
time = np.arange(len(aligned_tibia_acc)) / fs
# Compute PTA (norm of each acceleration vector at each time step)
pta = np.linalg.norm(aligned_tibia_acc, axis=1)
# Plot PTA over time
plt.figure(figsize=(10, 6))
plt.plot(time, pta, label='PTA (m/s^2)', color='b')
plt.xlabel('Time (s)')
plt.ylabel('PTA (m/s^2)')
plt.title('Peak Tibial Acceleration Over Time')
plt.grid(True)
plt.legend()
plt.show()
В настоящее время я работаю над проектом, целью которого является интеграция системы захвата движения IMU для обеспечения вибротактильной обратной связи через вибромоторы. Проект ориентирован на бегунов и может быть использован либо для повышения производительности, либо для предотвращения травм. Прямо сейчас я сосредоточен на использовании ИДУ для сбора необходимых параметров, в данном случае — ускорения большеберцовой кости. Я работал над алгоритмом калибровки датчика по сегменту и уже получил некоторые результаты, в достоверности которых я не совсем уверен. Я надеялся, что кто-нибудь сможет дать мне какой-нибудь совет или сказать, если я упускаю что-то важное. Некоторая актуальная информация: [list][*]Я использую датчики Movella Dot, которые уже позволяют определить ориентацию датчика с помощью фильтра Калмана.
[*] Я размещаю датчик в медиальной передней части голени (костной части).
[*]Пока я проведение статической и функциональной калибровки. Где статика — это короткая запись стоя, а функционал — запись медленной ходьбы. При статической калибровке я получаю вертикальную ось, измеряющую вектор гравитации. Из функциональной калибровки я получаю передне-заднюю ось, используя анализ главных компонентов записи ускорения. Наконец, я просто корректирую оси, чтобы обеспечить ортогональность, вычисляю ось Y как векторное произведение, нормализую и, наконец, получаю матрицу преобразования.
[/list] Вот что у меня есть на данный момент: import numpy as np import pandas as pd from scipy import signal from scipy.spatial.transform import Rotation as R from sklearn.decomposition import PCA from sklearn.preprocessing import StandardScaler import matplotlib.pyplot as plt
# Butterworth filter def filtering(fs, cutoff, data): order = 2 b, a = signal.butter(order, (2 * cutoff / fs), btype='low') filt_data = signal.filtfilt(b, a, data, axis=0) return filt_data
# Extract accelerometer, gyroscope, and quaternion data def get_data(filename): data = pd.read_csv(filename, delimiter=',', header=0)
# Rotate accelerometer data to global frame using quaternions a_global = np.zeros((N, 3)) for i in range(120, N-1): q = quaternions[i] # Get quaternion for this sample a_global[i, :] = rotate_vector(q, acc_data[i, :]) # Rotate using quaternion
# Filter the rotated accelerometer data a_global_filtered = filtering(fs, 15, a_global)
# Estimate gravity vector during the static upright position Tstart, Tend = 0, N # Replace with actual indices for static period gravity_vector = np.mean(a_global_filtered[Tstart:Tend, :], axis=0) gravity_magnitude = np.linalg.norm(gravity_vector) sensor_z_axis = gravity_vector
return sensor_z_axis, a_global_filtered, gyr_data
# Functional calibration: Rotate raw data and apply PCA to define X-axis (NOT NORMALIZED) def functional_calibration(filename): [acc_data,_, quaternions] = get_data(filename)
fs = 120 N = len(acc_data)
# Rotate accelerometer data to global frame using quaternions a_global = np.zeros((N, 3)) for i in range(120, N-1): q = quaternions[i] # Get quaternion for this sample a_global[i, :] = rotate_vector(q, acc_data[i, :]) # Rotate using quaternion
# Filter the rotated accelerometer data a_global_filtered = filtering(fs, 15, a_global)
# Now apply PCA to rotated accelerometer data to define the X-axis scaler = StandardScaler() a_global_scaled = scaler.fit_transform(a_global_filtered)
# Compute Y-axis to ensure orthogonality and right-handed system def gram_schmidt(sensor_x_axis, sensor_z_axis): # Apply Gram-Schmidt process to get orthogonal vectors sensor_x_axis_corrected = sensor_x_axis - (np.dot(sensor_x_axis, sensor_z_axis)/np.dot(sensor_z_axis, sensor_z_axis)) * sensor_z_axis
# Compute Y-axis as cross product of Z and X to enforce right-handed system sensor_y_axis = np.cross(sensor_x_axis_corrected, sensor_z_axis)
# Plot raw vs aligned acceleration fig, axs = plt.subplots(3, 1, figsize=(10, 8))
for i, axis in enumerate(['X', 'Y', 'Z']): axs[i].plot(time, a_global[:, i], label=f'Raw {axis}') axs[i].plot(time, aligned_acc[:, i], label=f'Aligned {axis}') axs[i].set_xlabel('Time (s)') axs[i].set_ylabel(f'Acceleration {axis} (m/s^2)') axs[i].legend() axs[i].grid(True)
plt.tight_layout() plt.show()
# Calculate and plot PTA (Peak Tibial Acceleration) over time def plot_pta(aligned_tibia_acc, fs=120): # Calculate time array time = np.arange(len(aligned_tibia_acc)) / fs
# Compute PTA (norm of each acceleration vector at each time step) pta = np.linalg.norm(aligned_tibia_acc, axis=1)
# Plot PTA over time plt.figure(figsize=(10, 6)) plt.plot(time, pta, label='PTA (m/s^2)', color='b') plt.xlabel('Time (s)') plt.ylabel('PTA (m/s^2)') plt.title('Peak Tibial Acceleration Over Time') plt.grid(True) plt.legend() plt.show()
Я обновляю свой предыдущий код Quantlib, чтобы калибровать параметры HW с помощью Cap. Я столкнулся с какой -то ошибкой, никогда не испытываемой раньше. Поскольку Quantlib версия 1.28 может работать, но 1.29 не может, угадайте разум может быть...
Я работаю над проектом, в котором использую датчик уровня воды для открытия/закрытия электромагнитного клапана для поддержания уровня воды.
В настоящее время я нахожусь на этапе использования Python для считывания выходных данных датчика. В моем...
Прошу прощения, если заголовок недостаточно ясен, но по сути я хочу иметь возможность собирать данные с датчиков только каждые несколько секунд. Я использую акселерометр и датчики GPS.
Все мои попытки добавить задержки к выводу не работают....
Прошу прощения, если заголовок недостаточно ясен, но по сути я хочу иметь возможность собирать данные с датчиков только каждые несколько секунд. Я использую акселерометр и датчики GPS.
Все мои попытки добавить задержки к выводу не работают....
Я не понимаю поведения DI в следующем случае.
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.Hosting;
using...