From: Derek Foreman <[email protected]> Use a smarter motion estimator that attempts to draw a best-fit line through the history where possible, including taking acceleration into account.
Signed-off-by: Derek Foreman <[email protected]> Reviewed-by: Daniel Stone <[email protected]> Reviewed-by: Simon Thum <[email protected]> --- src/synaptics.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 52 insertions(+), 4 deletions(-) v2: Split a few hunks out into separate patches. NOTE: I realise 'outlier' is unused; I've already fixed this in my local tree. diff --git a/src/synaptics.c b/src/synaptics.c index 23751f4..cfd1384 100644 --- a/src/synaptics.c +++ b/src/synaptics.c @@ -1803,6 +1803,54 @@ get_edge_speed(SynapticsPrivate *priv, const struct SynapticsHwState *hw, } } +/* + * Fit a line through the three most recent points in the motion + * history and return relative co-ordinates. + */ +static void regress(SynapticsPrivate *priv, const struct SynapticsHwState *hw, + double *dx, double *dy) +{ + const SynapticsParameters *pars = &priv->synpara; + int i, j; + double ym = 0, xm = 0, tm = 0; + double yb1n = 0, xb1n = 0, b1d = 0, xb1, yb1; + double dista, distb, distc, vela, velb, velc, acca, accb, jerk; + + if (priv->count_packet_finger == 1) { + *dx = hw->x - HIST(0).x; + *dy = hw->y - HIST(0).y; + return; + } + + /* Determine the best fit line through the 3 most recent history entries */ + for (i = 0; i < MIN(priv->count_packet_finger, 3); i++) { + ym += HIST(i).y; + xm += HIST(i).x; + tm += HIST_DELTA(i, 0, millis); + } + ym /= MIN(priv->count_packet_finger, 3); + tm /= MIN(priv->count_packet_finger, 3); + xm /= MIN(priv->count_packet_finger, 3); + + for (i = 0; i < MIN(priv->count_packet_finger, 3); i++) { + double t = HIST_DELTA(i, 0, millis); + yb1n += (t - tm) * (HIST(i).y - ym); + xb1n += (t - tm) * (HIST(i).x - xm); + b1d += (t - tm) * (t - tm); + } + xb1 = xb1n/b1d; + yb1 = yb1n/b1d; + + *dx = -xb1 * (HIST(0).millis - hw->millis); + *dy = -yb1 * (HIST(0).millis - hw->millis); + return; + +filtered: + *dx = 0; + *dy = 0; + priv->count_packet_finger = 0; +} + static void get_delta(SynapticsPrivate *priv, const struct SynapticsHwState *hw, edge_type edge, double *dx, double *dy) @@ -1813,10 +1861,10 @@ get_delta(SynapticsPrivate *priv, const struct SynapticsHwState *hw, double tmpf; int x_edge_speed = 0; int y_edge_speed = 0; + Bool outlier = FALSE; - /* HIST is full enough: priv->count_packet_finger > 3 */ - *dx = estimate_delta(hw->x, HIST(0).x, HIST(1).x, HIST(2).x); - *dy = estimate_delta(hw->y, HIST(0).y, HIST(1).y, HIST(2).y); + /* regress() performs the actual motion prediction. */ + regress(priv, hw, dx, dy); if ((priv->tap_state == TS_DRAG) || para->edge_motion_use_always) get_edge_speed(priv, hw, edge, &x_edge_speed, &y_edge_speed); @@ -1877,7 +1925,7 @@ ComputeDeltas(SynapticsPrivate *priv, const struct SynapticsHwState *hw, * POLL_MS declaration. */ delay = MIN(delay, POLL_MS); - if (priv->count_packet_finger <= 3) /* min. 3 packets, see get_delta() */ + if (priv->count_packet_finger < 1) /* min. 1 packet, see regress() */ goto out; /* skip the lot */ if (priv->moving_state == MS_TRACKSTICK) -- 1.7.5.3 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
