You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

时间积分结果异常:基于Pandas的加速度转位置计算偏差问题

Fixing Acceleration Integration for Position Calculation: Correcting Scipy & Resampling Logic

Let's break down what's going wrong in your code and fix it step by step—your approach is on the right track, but a few key missteps are causing the incorrect results.

What's Wrong With the Original Code?

  1. Misusing Rolling Window Integration: The rolling().apply(integrate.trapz) call computes the integral over a sliding window, not the cumulative integral from the start time to the current time. This leads to repeated calculations and inflated values, which explains why your results are way larger than manual Excel calculations.
  2. Undefined timedelta_base: Your code references this variable but doesn't define it—this would cause unpredictable resampling intervals, messing up the entire workflow.
  3. Ignoring Initial Conditions: Integration requires starting values (initial velocity and position, usually 0 if not specified), which weren't explicitly handled.
  4. Zero Results Without Resampling: When you skip resampling, the rolling window likely only includes a single data point each time. The trapezoidal integral of a single point is zero, hence the all-zero DataFrame.

Corrected Code

Here's a revised version that fixes all these issues and aligns with your goal of generating position data for Blender keyframes:

import pandas as pd
from scipy import integrate

# 1. Configure Blender frame rate and time base
cur_fps = 25  # Match your Blender scene's FPS
frame_interval = 1 / cur_fps  # Time per frame (e.g., 0.04s for 25fps)
timedelta_us = frame_interval * 1_000_000  # Convert to microseconds for pandas resample

# 2. Load acceleration data
acc_table = pd.read_excel("C:/Temp/exampleaccelerations.xlsx", index_col=0)
# Convert numeric time (seconds) to pandas timedelta for reliable resampling
acc_table.index = pd.to_timedelta(acc_table.index, unit="s")

# 3. Resample to Blender's frame interval (linear interpolation to fill gaps)
acc_interpolated = acc_table.resample(f"{timedelta_us}us").interpolate(method="linear")

# 4. Calculate time intervals (in seconds) for integration
dt = acc_interpolated.index.total_seconds().diff().fillna(0)

# 5. First integral: Acceleration → Velocity (cumulative trapezoidal integration)
vel_x = integrate.cumulative_trapezoid(acc_interpolated["acc_x"], dx=dt, initial=0)
vel_y = integrate.cumulative_trapezoid(acc_interpolated["acc_y"], dx=dt, initial=0)
vel_table = pd.DataFrame({"vel_x": vel_x, "vel_y": vel_y}, index=acc_interpolated.index)

# 6. Second integral: Velocity → Position (cumulative trapezoidal integration)
pos_x = integrate.cumulative_trapezoid(vel_table["vel_x"], dx=dt, initial=0)
pos_y = integrate.cumulative_trapezoid(vel_table["vel_y"], dx=dt, initial=0)
pos_table = pd.DataFrame({"pos_x": pos_x, "pos_y": pos_y}, index=acc_interpolated.index)

# 7. Prepare data for Blender keyframes (align with frame numbers)
pos_for_blender = pos_table.resample(f"{timedelta_us}us").first()
pos_for_blender["frame"] = range(1, len(pos_for_blender) + 1)
print(pos_for_blender)

Key Improvements Explained

  • Cumulative Integration: scipy.integrate.cumulative_trapezoid is designed exactly for this use case—it computes the integral from the start of the dataset to each point, which is what we need to get velocity from acceleration, then position from velocity. No more sliding window errors.
  • Explicit Time Handling: Converting the time index to timedelta ensures pandas resamples correctly, avoiding confusion between numeric seconds and datetime formats.
  • Accurate Time Intervals: Calculating dt directly from the interpolated time index ensures we use the exact time between each data point for integration, which is critical for accuracy.
  • Initial Conditions: The initial=0 parameter sets starting velocity and position to 0 (adjust this if your object has an initial velocity/position).
  • Blender Alignment: Resampling to the exact frame interval ensures each row in pos_for_blender corresponds to a Blender frame, making it easy to import as keyframes.

How to Verify

To check if the results are correct, compare the first few values to manual calculations. For example:

  • Between 0.1s and 0.2s, the x-acceleration goes from 0 to -0.98. The trapezoidal integral (velocity change) is (0 + (-0.98)) * 0.1 / 2 = -0.049—your vel_x value at 0.2s should match this.

内容的提问来源于stack exchange,提问作者haarigertroll

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 13:37:50