Алгоритм синхронизации — различия между версиями
Korvin (обсуждение | вклад) |
Korvin (обсуждение | вклад) м |
||
Строка 56: | Строка 56: | ||
\end{cases} | \end{cases} | ||
</math> | </math> | ||
+ | |||
+ | |||
+ | == Механизм коррекции ошибки == | ||
+ | |||
+ | В идеальном случае, при нулевой задержке времени между клиентом и сервером, а также при достаточно большой частоте обновлений, рассинхронизация между миром клиента и миром сервера была бы пренебрежимо мала. Однако, суровая реальность говорит обратное. В результате, клиентская часть, по сути, находится в прошлом от серверной (на время половины пинга). Поэтому, возникает необходимость подгонять траекторию движения клиентских тел так, чтобы она коррелировала с эталонной, серверной траекторией, опорные точки которой мы получаем. | ||
+ | |||
+ | Коррекция осуществляется путем приложения сторонней силы к движущемуся телу так, чтобы "подтолкнуть" его в сторону желаемой траектории. Коррекция осуществляется в отношении собственно координаты тела и в отношении вектора его скорости. Опять же, в идеальном случае, скорректированная траектория полностью накладывается на серверную, вплоть до равенства параметров в соответствующих точках. Задача сводится к нахождению дифференциального уравнения соответствующей силы, а также определению граничных параметров, которые позволят выполнить коррекцию гладко, без перерегулирования. | ||
+ | |||
+ | Чтобы упростить себе жизнь, рассмотрим одномерный случай. Пусть серверная "траектория" находится в точке 0; клиентская "траектория" - в точке с координатой H. Графически, это выглядит как вертикальная линия, в нуле -- серверная траектория, в точке на высоте H -- клиентская. Горизонтальную и вертикальную компоненты скорости будем рассматривать отдельно. | ||
+ | |||
+ | Пусть серверная точка имеет горизонтальную скорость <math>V_x</math>. Клиентская, в самом начале -- горизонтальную скорость <math>V_x</math> и вертикальную, равную нулю. | ||
+ | |||
+ | |||
+ | Сила коррекции высоты, по такой модели, будет направлена "вниз" на эту точку, и будет равна: | ||
+ | :<math>F_p = K_p \cdot y(t) \cdot V_x</math> | ||
+ | где <math>y</math> -- это высота точки и | ||
+ | :<math>y(0) = H\!</math> | ||
+ | |||
+ | |||
+ | |||
+ | [01:46:49] <droot@deeptown.org> тьфу, это сила коррекции высоты | ||
+ | [01:47:13] <droot@deeptown.org> Fp = Kp * y(t) * Vx | ||
+ | [01:47:31] <droot@deeptown.org> (массу будем считать равной 1 для простоты) | ||
+ | [01:48:14] <droot@deeptown.org> для скорости: Fv = Kv * Vy(t), где Vy(t) - вертикальная скорость точки; Vy(0) = 0 | ||
+ | [01:49:18] <droot@deeptown.org> ну и отношение, соответственно - Vy(t) = d( y(t) ) / dt | ||
+ | [01:49:34] <droot@deeptown.org> (скорость - это производная координаты по времени) | ||
+ | [01:49:52] <korvin> ну эт понятно да | ||
+ | [01:50:38] <droot@deeptown.org> соответственно, сила, которая действует на объект: | ||
+ | [01:51:26] <droot@deeptown.org> F(t) = Fp + Fv = Kp * y(t) * Vx + Kv * Vy(t) = Kp * y(t) * Vx + Kv * y'(t) | ||
+ | [01:51:59] <droot@deeptown.org> вот тебе типа дифур =) |
Версия 16:15, 22 октября 2008
Здесь будет рассмотрена математическая составляющая алгоритмов синхронизации физики. Понимающих в этом деле, просьба прокомментировать.
Построение сплайна
Для синхронизации была выбрана форма кубических сплайнов, при которой за основу берутся значения функции и ее производной в двух точках.
Свойства сплайна:
- <math>s(t_i) = f(t_i) = , \quad s'(t_i) = f'(t_i)\!</math>
Уравнение сплайна:
- <math>s(t) = a + bt + ct^2 + dt^3\!</math>
Для нахождения коэффициентов <math>a, b, c, d</math> записываем систему уравнений:
- <math>\begin{cases}
a + bt_0 + ct_0^2 + dt_0^3 = f(t_0) \\ a + bt_1 + ct_1^2 + dt_1^3 = f(t_1) \\ b + 2ct_0 + 3dt_0^2 = f'(t_0) \\ b + 2ct_1 + 3dt_1^2 = f'(t_1) \end{cases} </math>
Подставляем известные значения в правой части системы (даны по условию):
- <math>\begin{cases}
a + bt_0 + ct_0^2 + dt_0^3 = x_0 \\ a + bt_1 + ct_1^2 + dt_1^3 = x_1 \\ b + 2ct_0 + 3dt_0^2 = v_0 \\ b + 2ct_1 + 3dt_1^2 = v_1 \end{cases} </math>
Поскольку сплайн не зависит от конкретных значений <math>t_0</math> и <math>t_1</math> положим <math>t_0 = 0</math>, а <math>t_1 = t</math>. В результате, пара уравнений становится тривиальной:
- <math>\begin{cases}
a = x_0 \\ a + bt_1 + ct_1^2 + dt_1^3 = x_1 \\ b = v_0 \\ b + 2ct_1 + 3dt_1^2 = v_1 \end{cases} </math>
Заменяем в оставшихся уравнениях известные теперь коэффициенты и получаем конечную систему:
- <math>\begin{cases}
x_0 + v_0t_1 + ct_1^2 + dt_1^3 = x_1 \\ v_0 + 2ct_1 + 3dt_1^2 = v_1 \end{cases} </math>
После нехитрых манипуляций, получаем выражения для оставшихся коэффициентов:
- <math>\begin{cases}
c = \frac{3x_1 - 3x_0 - 2v_0t - v_1t}{t^2} \\ d = \frac{v_1t - 2x_1 + 2x_0 + v_ot}{t^3} \end{cases} </math>
Механизм коррекции ошибки
В идеальном случае, при нулевой задержке времени между клиентом и сервером, а также при достаточно большой частоте обновлений, рассинхронизация между миром клиента и миром сервера была бы пренебрежимо мала. Однако, суровая реальность говорит обратное. В результате, клиентская часть, по сути, находится в прошлом от серверной (на время половины пинга). Поэтому, возникает необходимость подгонять траекторию движения клиентских тел так, чтобы она коррелировала с эталонной, серверной траекторией, опорные точки которой мы получаем.
Коррекция осуществляется путем приложения сторонней силы к движущемуся телу так, чтобы "подтолкнуть" его в сторону желаемой траектории. Коррекция осуществляется в отношении собственно координаты тела и в отношении вектора его скорости. Опять же, в идеальном случае, скорректированная траектория полностью накладывается на серверную, вплоть до равенства параметров в соответствующих точках. Задача сводится к нахождению дифференциального уравнения соответствующей силы, а также определению граничных параметров, которые позволят выполнить коррекцию гладко, без перерегулирования.
Чтобы упростить себе жизнь, рассмотрим одномерный случай. Пусть серверная "траектория" находится в точке 0; клиентская "траектория" - в точке с координатой H. Графически, это выглядит как вертикальная линия, в нуле -- серверная траектория, в точке на высоте H -- клиентская. Горизонтальную и вертикальную компоненты скорости будем рассматривать отдельно.
Пусть серверная точка имеет горизонтальную скорость <math>V_x</math>. Клиентская, в самом начале -- горизонтальную скорость <math>V_x</math> и вертикальную, равную нулю.
Сила коррекции высоты, по такой модели, будет направлена "вниз" на эту точку, и будет равна:
- <math>F_p = K_p \cdot y(t) \cdot V_x</math>
где <math>y</math> -- это высота точки и
- <math>y(0) = H\!</math>
[01:46:49] <droot@deeptown.org> тьфу, это сила коррекции высоты [01:47:13] <droot@deeptown.org> Fp = Kp * y(t) * Vx [01:47:31] <droot@deeptown.org> (массу будем считать равной 1 для простоты) [01:48:14] <droot@deeptown.org> для скорости: Fv = Kv * Vy(t), где Vy(t) - вертикальная скорость точки; Vy(0) = 0 [01:49:18] <droot@deeptown.org> ну и отношение, соответственно - Vy(t) = d( y(t) ) / dt [01:49:34] <droot@deeptown.org> (скорость - это производная координаты по времени) [01:49:52] <korvin> ну эт понятно да [01:50:38] <droot@deeptown.org> соответственно, сила, которая действует на объект: [01:51:26] <droot@deeptown.org> F(t) = Fp + Fv = Kp * y(t) * Vx + Kv * Vy(t) = Kp * y(t) * Vx + Kv * y'(t) [01:51:59] <droot@deeptown.org> вот тебе типа дифур =)