Рассчитать положение дифференциального привода робота

14

Как рассчитать или обновить положение робота с дифференциальным приводом с помощью инкрементальных датчиков?

К каждому из двух колес дифференциала подключен один инкрементальный датчик. Оба датчика определяют расстояние соответственно. Δ r i g h t их колесо катилось в течение известного времени Δ t .ΔleftΔrightΔt

Во-первых, давайте предположим, что центр между двумя колесами отмечает положение робота. В этом случае можно рассчитать позицию как:

x=xleft+xright2y=yleft+yright2

«Выводя» эти уравнения в предположении, что оба колеса катятся по прямой (что должно быть приблизительно правильно для небольших расстояний), я получаю:

ΔxΔt=12(ΔleftΔt+ΔrightΔt)cos(θ)ΔyΔt=12(ΔleftΔt+ΔrightΔt)sin(θ)

Где - угол ориентации робота. Для изменения этого угла я нашел уравнениеθ

ΔθΔt=1w(ΔleftΔtΔrightΔt)

Где - расстояние между обоими колесами.w

ΔxΔyθθΔθθ

xy

x=xleft+xright2+lcos(θ)y=yleft+yright2+lsin(θ)

«Вывод» первый дает:

ΔxΔt=12(ΔleftΔt+ΔrightΔt)cos(θ)lsin(θ)ΔθΔt

Δθθ ?

Есть ли лучший способ сделать одновременное обновление позиции и ориентации? Может быть, использовать комплексные числа (такой же подход, как с кватернионами в 3D?) Или однородные координаты?

Даниэль Жур
источник

Ответы:

8

Чтобы ответить на ваш первый вопрос: если вы действительно хотите найти истинные кинематические уравнения для дифференциального привода, я бы не стал приближаться, предполагая, что каждое колесо движется по прямой. Вместо этого найдите радиус поворота, рассчитайте центральную точку дуги, а затем вычислите следующую точку робота. Радиус поворота будет бесконечным, если робот движется прямо, но в прямом случае математика проста.

Итак, просто представьте, что на каждом временном шаге или каждый раз, когда вы вычисляете изменение в инкрементальных датчиках, робот перемещается из точки A в точку B по дуге, как это: введите описание изображения здесь Вот пример кода с упрощенной математикой:

// leftDelta and rightDelta = distance that the left and right wheel have moved along
//  the ground

if (fabs(leftDelta - rightDelta) < 1.0e-6) { // basically going straight
    new_x = x + leftDelta * cos(heading);
    new_y = y + rightDelta * sin(heading);
    new_heading = heading;
} else {
    float R = unitsAxisWidth * (leftDelta + rightDelta) / (2 * (rightDelta - leftDelta)),
          wd = (rightDelta - leftDelta) / unitsAxisWidth;

    new_x = x + R * sin(wd + heading) - R * sin(heading);
    new_y = y - R * cos(wd + heading) + R * cos(heading);
    new_heading = boundAngle(heading + wd);
}

Я использовал подобную математику в симуляторе, чтобы продемонстрировать различные способы управления: http://www.cs.utexas.edu/~rjnevels/RobotSimulator4/demos/SteeringDemo/

Robz
источник
1
Уравнения, использованные в приведенном выше фрагменте кода, получены здесь: rossum.sourceforge.net/papers/DiffSteer
kamek
Отличное объяснение! Ссылка Тренажер сломана
smirkingman
2

ΔθθΔx,Δy

ΔθΔx,Δyθ .

Δt0

Ян
источник
Поиск «прямой кинематики транспортных средств с дифференциальным приводом» должен дать ряд статей с более математическим подходом к этому вопросу.
Ян