做到这一点的一种方法是定义轨道的开始,然后通过路径的归一化弧长参数化循环周围的每个遍历。然后,您可以使用此参数化在沿着轨道的特定间隔内插每条曲线,并对结果进行平均。
% 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(:)];
注:findpeaks
和smooth
是可能被MATLAB文件交换中的函数替换的工具箱函数。或者,如果您知道已知道,那么您可以完全取消findpeaks
的使用。
您的轨道是圆形的吗? – Suever
在这种情况下,它实际上是一个圆角矩形,但理想情况下,我想要一个适用于任何轨道形状的解决方案 – enrico
您是否打算制作轨道地图(因为您不知道轨道)或更准确地跟踪汽车的动作(你知道轨道的形状)? – Wolfie