【问题标题】:Averaging periodic data with a variable sampling rate以可变采样率平均周期性数据
【发布时间】:2017-04-13 13:43:36
【问题描述】:

我有一长串[x,y] 玩具车在轨道上跑了 5-6 圈的坐标值。每圈数据点的数量不一致(每圈有 50-60 [x,y] 点)。 Matlab 中绘制的数据是有意义的,它绘制了汽车在轨道上移动时的情况:

但是,我需要以某种方式对嘈杂的圈数进行平均,以创建更准确的单一赛道地图。

我尝试在赛道上标记起点,以便确定新圈的起点,然后平均每圈的每个对应点,但是由于每圈的数据点数量不同,这会导致更多错误。

我考虑过对[x,y] 数据进行排序以将所有点连接到一圈,但这不起作用,因为赛道是圆形的。

有人知道以某种方式将我的数据平均以将圈数合并在一起的方法吗?

【问题讨论】:

  • 你的赛道是圆形的吗?
  • 在这种情况下它实际上是一个圆角矩形,但理想情况下我想要一个适用于任何轨道形状的解决方案
  • 您的目标是制作赛道地图(因为您不了解赛道)还是更准确地跟踪汽车的运动(并且您知道赛道的形状)?
  • @Wolfie 车速是恒定的,但我没有为此情节收集任何时间数据。时间有助于将各圈合并在一起吗? - 我只需要知道未知轨道的大致形状。

标签: matlab average interpolation


【解决方案1】:

执行此操作的一种方法是定义轨道的起点,然后通过路径的标准化弧长参数化循环周围的每个遍历。然后,您可以使用此参数化沿轨道以特定间隔对每条曲线进行插值,并对结果进行平均。

% Assume that the first point is the start point (t = 0)
start_point = path(1,:);

% Compute the distance to this point for all data points
distances = sqrt(sum(bsxfun(@minus, path, start_point).^2, 2));

% Find the minima of this curve (these are all the times that the car passed the start)
% We apply some smoothing to get rid of necessary noise. Really depends on your data
[~, locs] = findpeaks(smooth(-distances, 20));

% Make sure we include the first and last point
locs = [1; locs; numel(distances)];

% Desired samples for each loop
nSamples = 1000;

% Pre-allocate the outputs
xpoints = zeros(numel(locs) - 1, nSamples);
ypoints = zeros(numel(locs) - 1, nSamples);

for k = 1:(numel(locs) - 1)
    % Get the coordinates recorded for this particular loop
    loop_points = path(locs(k):locs(k+1),:);

    % Compute the cumulative arc-length using these points
    arc_length = cumsum([0; sum(diff(loop_points, [], 1).^2, 2)]);

    % Normalize the arc_length between 0 and 1
    arc_length = arc_length ./ arc_length(end);

    % Interpolate along the curve
    xpoints(k,:) = interp1(arc_length, loop_points(:,1), linspace(0, 1, nSamples));
    ypoints(k,:) = interp1(arc_length, loop_points(:,2), linspace(0, 1, nSamples));
end

% Average all the x and y locations
X = mean(xpoints, 1);
Y = mean(ypoints, 1);

plot(X, Y)

我们可以通过一个完美的循环来测试这一点,并在每个电路中添加一些噪声并每次更改样本数量

nLoops = 10;

x = [];
y = [];

for k = 1:nLoops
    nSamples = randi([50, 70]);

    t = linspace(0, 2*pi, nSamples + 1);
    t(end) = [];

    x = cat(1, x(:), cos(t(:)) + 0.1 * (rand(size(t(:))) - 0.5));
    y = cat(1, y(:), sin(t(:)) + 0.1 * (rand(size(t(:))) - 0.5));
end

path = [x(:), y(:)];

注意:findpeakssmooth 是工具箱函数,可能会被 MATLAB File Exchange 中的函数替换。或者,如果您知道汽车何时通过起点,则可以完全删除 findpeaks 的使用。

【讨论】:

  • 这在您的演示中似乎非常有效。或许值得一提的是findpeakssmooth 分别使用了信号处理和曲线拟合工具箱。
  • @Wolfie 更新了警告
  • @Suever 谢谢这似乎是一个很好的解决方案,但是我的数据出现了一些 Matlab 错误。当我进入 for 循环时,它停止运行并显示“网格向量不是严格单调递增的”。你知道这意味着什么吗?
  • @enrico 你在同一个位置有多个点吗?检查 locs 在特定迭代中的值是什么
  • 啊,是的,谢谢!现在可以正常工作,删除重复项
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-17
  • 1970-01-01
  • 1970-01-01
  • 2017-07-12
  • 1970-01-01
  • 1970-01-01
  • 2019-07-12
相关资源
最近更新 更多