Exemple #1
0
/**
 * Calculate the velocity based on the tracker data. Velocity is averaged
 * across multiple historical values, provided those values aren't "too
 * different" to our current one. That includes either being too far in the
 * past, moving into a different direction or having too much of a velocity
 * change between events.
 */
static double
calculate_velocity(struct pointer_accelerator *accel, uint64_t time)
{
	struct pointer_tracker *tracker;
	double velocity;
	double result = 0.0;
	double initial_velocity = 0.0;
	double velocity_diff;
	unsigned int offset;

	unsigned int dir = tracker_by_offset(accel, 0)->dir;

	/* Find least recent vector within a timelimit, maximum velocity diff
	 * and direction threshold. */
	for (offset = 1; offset < NUM_POINTER_TRACKERS; offset++) {
		tracker = tracker_by_offset(accel, offset);

		/* Bug: time running backwards */
		if (tracker->time > time)
			break;

		/* Stop if too far away in time */
		if (time - tracker->time > MOTION_TIMEOUT) {
			if (offset == 1)
				result = calculate_velocity_after_timeout(accel, tracker);
			break;
		}

		velocity = calculate_tracker_velocity(accel, tracker, time);

		/* Stop if direction changed */
		dir &= tracker->dir;
		if (dir == 0) {
			/* First movement after dirchange - velocity is that
			 * of the last movement */
			if (offset == 1)
				result = velocity;
			break;
		}

		if (initial_velocity == 0.0) {
			result = initial_velocity = velocity;
		} else {
			/* Stop if velocity differs too much from initial */
			velocity_diff = fabs(initial_velocity - velocity);
			if (velocity_diff > MAX_VELOCITY_DIFF)
				break;

			result = velocity;
		}
	}

	return result; /* units/us */
}
Exemple #2
0
static double
calculate_velocity(struct pointer_accelerator *accel, uint32_t time)
{
	struct pointer_tracker *tracker;
	double velocity;
	double result = 0.0;
	double initial_velocity;
	double velocity_diff;
	unsigned int offset;

	unsigned int dir = tracker_by_offset(accel, 0)->dir;

	/* Find first velocity */
	for (offset = 1; offset < NUM_POINTER_TRACKERS; offset++) {
		tracker = tracker_by_offset(accel, offset);

		if (time <= tracker->time)
			continue;

		result = initial_velocity =
			calculate_tracker_velocity(tracker, time);
		if (initial_velocity > 0.0)
			break;
	}

	/* Find least recent vector within a timelimit, maximum velocity diff
	 * and direction threshold. */
	for (; offset < NUM_POINTER_TRACKERS; offset++) {
		tracker = tracker_by_offset(accel, offset);

		/* Stop if too far away in time */
		if (time - tracker->time > MOTION_TIMEOUT ||
		    tracker->time > time)
			break;

		/* Stop if direction changed */
		dir &= tracker->dir;
		if (dir == 0)
			break;

		velocity = calculate_tracker_velocity(tracker, time);

		/* Stop if velocity differs too much from initial */
		velocity_diff = fabs(initial_velocity - velocity);
		if (velocity_diff > MAX_VELOCITY_DIFF)
			break;

		result = velocity;
	}

	return result;
}
Exemple #3
0
static void
accelerator_restart(struct motion_filter *filter,
		    void *data,
		    uint64_t time)
{
	struct pointer_accelerator *accel =
		(struct pointer_accelerator *) filter;
	unsigned int offset;
	struct pointer_tracker *tracker;

	for (offset = 1; offset < NUM_POINTER_TRACKERS; offset++) {
		tracker = tracker_by_offset(accel, offset);
		tracker->time = 0;
		tracker->dir = 0;
		tracker->delta.x = 0;
		tracker->delta.y = 0;
	}

	tracker = tracker_by_offset(accel, 0);
	tracker->time = time;
	tracker->dir = UNDEFINED_DIRECTION;
}