Карта наименьших квадратов

10

Здесь много предыстории, прокрутите вниз для вопроса

Я пробую алгоритм объединения карт, описанный в разделе Как далеко находится SLAM от линейной задачи наименьших квадратов ; в частности, формула (36). Код, который я написал, кажется, всегда принимает значения второй карты для ориентиров. У меня вопрос, правильно ли я понимаю текст или я делаю какую-то ошибку. Я попытаюсь объяснить формулы, как я их понимаю, и покажу, как мой код реализует это. Я пытаюсь сделать простой случай объединения двух локальных карт.

В статье (36) говорится, что объединение двух локальных карт позволяет найти вектор состояния который минимизирует:ИксJояN,реL

ΣJзнак равно1К(ИксJL^-ЧАСJ,реL(ИксJояN,реL))T(пJL)-1(ИксJL^-ЧАСJ,реL(ИксJояN,реL))

Расширен для двух локальных карт и меня есть: ^ X L 2Икс1L^Икс2L^

(Икс1L^-ЧАСJ,реL(ИксJояN,реL))T(п1L)-1(Икс1L^-ЧАСJ,реL(ИксJояN,реL))+(Икс2L^-ЧАСJ,реL(ИксJояN,реL))T(п2L)-1(Икс2L^-ЧАСJ,реL(ИксJояN,реL))

Насколько я понимаю, подкарта может рассматриваться как интегрированное наблюдение для глобальной карты, поэтому - это шум, связанный с подкартой (в отличие от шума процесса в EKF, который я использовал для создания подкарты, который может или может не отличаться).пJL

Вектор - это поза с первой карты, поза со второй карты и объединение ориентиров на обеих картах.ИксJояN,реL

Функция :ЧАСJ,реL

[ИксрJер(J-1)еφрJер(J-1)ер(φр(J-1)ермJ1е)(ИксеJ1рмJ1е-Икср(J-1)ермJ1е),,,р(φр(J-1)ермJLе)(ИксеJLрмJLе-Икср(J-1)ермJLе)ИксеJ(L+1)рJ-1е,,,ИксеJNрJ-1е]

Я не уверен, что моя оценка ниже верна:

Первые два элемента представляют собой позу робота в системе координат предыдущей карты. Например, для карты 1 поза будет в начальном кадре в ; для карты 2 это будет в кадре карты 1.T0

Следующая группа элементов - это элементы, общие для карты 1 и карты 2, которые преобразуются в систему отсчета карты 1.

Последние строки - это элементы, уникальные для карты 2, в кадре первой карты.

Моя реализация Matlab выглядит следующим образом:

function [G, fval, output, exitflag] = join_maps(m1, m2)
    x = [m2(1:3);m2];
    [G,fval,exitflag,output] = fminunc(@(x) fitness(x, m1, m2), x, options);
end

function G = fitness(X, m1, m2)
    m1_f = m1(6:3:end);
    m2_f = m2(6:3:end);
    common = intersect(m1_f, m2_f);
    P = eye(size(m1, 1)) * .002;
    r = X(1:2);
    a = X(3);
    X_join = (m1 - H(X, common));
    Y_join = (m2 - H(X, common));
    G = (X_join' * inv(P) * X_join) + (Y_join' * inv(P) * Y_join);
end

function H_j = H(X, com)
    a0 = X(3);
    H_j = zeros(size(X(4:end)));
    H_j(1:3) = X(4:6);
    Y = X(1:2);
    len = length(X(7:end));
    for i = 7:3:len
        id = X(i + 2);
        if find(com == id)
            H_j(i:i+1) = R(a0) * (X(i:i+1) - Y);
            H_j(i+2) = id;
        else  % new lmk
            H_j(i:i+2) = X(i:i+2);
        end
    end
end

function A = R(a)
    A = [cos(a) -sin(a); 
         sin(a)  cos(a)];
end

Я использую панель инструментов оптимизации, чтобы найти минимум фитнес-функции, описанной выше. Я думаю, что сама функция фитнеса довольно проста. Функция H возвращает вектор H, описанный выше.

Результат: Когда я запускаю join_maps для двух векторов

map_1 = [3.7054;1.0577;-1.9404; %robot x, y, angle
      2.5305;-1.0739;81.0000]; % landmark x, y, id
map_2 = [3.7054;1.0577;-1.9404;
         2.3402;-1.1463;81.0000]; % note the slightly different x,y

[G,fv,output,exitflag] = join_maps(map_1, map_2)

Выход:

Warning: Gradient must be provided for trust-region algorithm;
  using line-search algorithm instead. 
> In fminunc at 341
  In join_maps at 7

Local minimum found.

Optimization completed because the size of the gradient is less than
the default value of the function tolerance.

<stopping criteria details>


Local minimum possible.

fminunc stopped because it cannot decrease the objective function
along the current search direction.

<stopping criteria details>

G = 
      3.7054
      1.0577
     -1.9404
      3.7054
      1.0577
     -1.9404
      2.3402
     -1.1463
      81.0000

 fv =
     1.3136e+07
  output = 
     iterations: 1
      funcCount: 520
       stepsize: 1.0491e-16
  firstorderopt: 1.6200e+05
      algorithm: 'medium-scale: Quasi-Newton line search'
        message: [1x362 char]
  exitflag =
   5

Вопрос:

Моя программа дает карту 2 - минимум функции присоединения к карте. Кажется, что минимум должен быть где-то между картой 1 и картой 2. Я почти уверен, что проблема с матрицей H. Что я делаю не так?

бурундук
источник

Ответы:

2

Кажется, это работает правильно и является гораздо более простым решением:

function [X, FVAL, EXITFLAG, OUTPUT, GRAD] = join_maps(m1, m2)
    p = [m1(1:3);m2(1:3)];
    x1 = [p;m1(4:end)];
    x2 = [p;m2(4:end)];
    guess_0 = zeros(size(x1,1),1);
    q = @(x)x'*eye(length(x))*x;
    fit = @(x)q(x1-x)+q(x2-x);
    [X,FVAL,EXITFLAG,OUTPUT,GRAD] = fminunc(fit ,guess_0);
end

Я изменил вывод, чтобы лучше соответствовать описанию для fminunc.

Выход с map_1 и map_2:

X =
 3.7054
 1.0577
-1.9404
 3.7054
 1.0577
-1.9404
 2.4353
-1.1101
 81.0000

В этом случае нет необходимости вызывать H (X), поскольку первые две позы идентичны, поэтому две карты имеют одинаковую систему отсчета. Функция H просто преобразует оценку состояния в систему отсчета подкарты.

бурундук
источник