[PATCH 07/15] Replace the motion estimator
Peter Hutterer
peter.hutterer at who-t.net
Mon Jun 13 21:59:43 PDT 2011
On Thu, Jun 09, 2011 at 08:57:28PM +0100, Daniel Stone wrote:
> From: Derek Foreman <derek.foreman at collabora.co.uk>
>
> 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 <derek.foreman at collabora.co.uk>
> Reviewed-by: Daniel Stone <daniel at fooishbar.org>
> ---
> src/synaptics.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++------
> 1 files changed, 68 insertions(+), 8 deletions(-)
>
> diff --git a/src/synaptics.c b/src/synaptics.c
> index 8a6d56e..fb37030 100644
> --- a/src/synaptics.c
> +++ b/src/synaptics.c
> @@ -1689,6 +1689,8 @@ store_history(SynapticsPrivate *priv, int x, int y, unsigned int millis)
> priv->move_hist[idx].y = y;
> priv->move_hist[idx].millis = millis;
> priv->hist_index = idx;
> + if (priv->count_packet_finger < SYNAPTICS_MOVE_HISTORY)
> + priv->count_packet_finger++;
> }
>
> /*
> @@ -1777,6 +1779,63 @@ 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.
> + *
> + * Three forms of filtering are present:
> + * Acceleration - pointer accelerating too fast
> + * Jerk - too great a change in pointer acceleration
> + * Error - hw state deviates too much from the predicted position
> + *
> + * Note - The current state is used for filtering, but only its time is used
> + * in the delta calculation
> + */
> +
> +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);
you're mixing tabs/spaces here. I'd prefer the code to be tab-indented,
that's the majority format here.
> + }
> + ym /= priv->count_packet_finger;
> + tm /= priv->count_packet_finger;
> + xm /= priv->count_packet_finger;
> +
> + 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 * (hw->millis - HIST(0).millis);
> + *dy = yb1 * (hw->millis - HIST(0).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)
> @@ -1787,10 +1846,11 @@ 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 */
this comment now seems to be misplaced
> - *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(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);
> @@ -1847,19 +1907,19 @@ ComputeDeltas(SynapticsPrivate *priv, const struct SynapticsHwState *hw,
> }
>
> /* to create fluid edge motion, call back 'soon'
> - * even in the absence of new hardware events */
> + * even in the absence of new hardware events
> + * Note: This should be longer that the device report rate!
> + */
> delay = MIN(delay, POLL_MS);
sigh, isn't this supposed to be in the POLL_MS patch?
>
> - if (priv->count_packet_finger <= 3) /* min. 3 packets, see get_delta() */
> - goto skip; /* skip the lot */
> + if (priv->count_packet_finger < 1) /* min. 1 packet, see regress() */
> + goto out; /* skip the lot */
>
> if (priv->moving_state == MS_TRACKSTICK)
> get_delta_for_trackstick(priv, hw, &dx, &dy);
> else if (moving_state == MS_TOUCHPAD_RELATIVE)
> get_delta(priv, hw, edge, &dx, &dy);
>
> -skip:
> - priv->count_packet_finger++;
> out:
> priv->prevFingers = hw->numFingers;
>
> @@ -2594,7 +2654,7 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
> priv->lastButtons = buttons;
>
> /* generate a history of the absolute positions */
> - if (inside_active_area)
> + if (inside_active_area && actual)
ooh, look. the actual is actually used now :)
misplaced hunk, should be elsewhere.
Cheers,
Peter
> store_history(priv, hw->x, hw->y, hw->millis);
>
> return delay;
> --
> 1.7.5.3
More information about the xorg-devel
mailing list