5

I am working with disabled children, who have cerebral palsy. One child has limited fine motor control, so she currently uses a joystick to control the mouse, and it's traverse rate is set very low. This works well for her, as she can click all buttons on the screen, but I think we could do better - when she wants to traverse the whole screen it takes an age to do so (about 10 seconds).

My hypothesis is that her brain is fine, and only her motor control is poor. If that's true, I believe that a mouse that started at a low speed, but experienced a constant acceleration, would be better for her, as it would pick up speed and become quick when traversing the whole screen. If this works, then we could be tweaking PID control, and velocity/acceleration setting for a great number of disabled people, speeding up their access and hence their learning and development.

But I do not know the best way to build this - all suggestions, thoughts, links and tips welcome.

To begin with I have tried using Processing and Java, and using a mouseListener, and a Robot to control the cursor. I'm not convinced that this is the best way though, as I'm reading the cursor position and then writing to it, so my best attempts still make the cursor jump around, and there is not smooth movement. Is it achievable in Java? Do I need to read the mouse input from the USB using some kind of driver, and then replace the plotting of the cursor on screen with my own?

I've made a couple of videos to illustrate the effect I am trying to bring about.

The Status quo (my illustration is driving the cursor off the arrow keys) http://www.youtube.com/watch?v=3ZhQCg5DJt8

The new behaviour I want (mouse accelerates) http://www.youtube.com/watch?v=JcBK_ZCFGPs

if it's any use, the Processing code I used to make those demos is copied in below:

Status quo demo:

import java.awt.AWTException;
import jav
a.awt.Robot;

Robot robot;
int i = 0;
int j = 0;

void setup() {
  setupDotgame();
  try { 
    robot = new Robot();
  } 
  catch (AWTException e) {
    e.printStackTrace();
  }
  robot.mouseMove(screenWidth/2, screenHeight/2);
}

void draw() {
  //println(frameCount);
  robot.mouseMove(screenWidth/2+8*i, screenHeight/2+8*j);
  drawDotgame();
}

void keyPressed() {
  if (keyCode == UP) {
    j--;
  } 
  else if (keyCode == DOWN) {
    j++;
  }
  else if (keyCode == RIGHT) {
    i++;
  }
  else if (keyCode == LEFT) {
    i--;
  }
}

Desired behaviour:

import java.awt.AWTException;
import java.awt.Robot;

Robot robot;
int i = 0;
int j = 0;
int delta = 8;
int time = 0;

void setup() {
  setupDotgame();
  try { 
    robot = new Robot();
  } 
  catch (AWTException e) {
    e.printStackTrace();
  }
  robot.mouseMove(screenWidth/2, screenHeight/2);
}

void draw() {



  //println(frameCount);
  robot.mouseMove(screenWidth/2+i, screenHeight/2+j);
  drawDotgame();

}

void keyPressed() {
  if (millis() - time < 90) {
    delta += 8;
  }
  else { delta = 8; }
  time = millis();


  if (keyCode == UP) {
    j-=delta;
  } 
  else if (keyCode == DOWN) {
    j+=delta;
  }
  else if (keyCode == RIGHT) {
    i+=delta;
  }
  else if (keyCode == LEFT) {
    i-=delta;
  }
}

And the DotGame code they both reference:

void setupDotgame() {
  size(1000, 600);
  background(255);
  fill(255, 0, 0);
  noStroke();
  smooth();
  drawCircle();
}

void drawDotgame() {
  if (get(mouseX, mouseY) != color(255)) {
    background(255);
    drawCircle();
  }
}

void drawCircle() {
  int x = round(random(50, width-50));
  int y = round(random(50, height-50));
  int rad = round(random(20, 80));
  ellipse(x, y, rad, rad);
}

Thanks in advance

Ryan B
  • 3,364
  • 21
  • 35
samjewell
  • 1,068
  • 11
  • 20
  • Have you considered using a button on the joystick to speed up movement. For example Ctrl+arrow makes the mouse move quickly when using MouseKeys. Similarly something that could make it jump if need be but still have the low speed the fine tuning requires? – cjds Feb 02 '13 at 10:51
  • Thanks for the suggestion. The student in question can only do one thing at a time with her hands really, so I'm not that optimistic about her being able to do two thing at once. Like I say, I think her brain is fine, but its lots of muscle spasming that makes things really difficult. – samjewell Feb 02 '13 at 10:58
  • 1
    I don't want to sound like a jerk, but is this a programming question you want answered, or are you trying to get a discussion going on the best way to do this? And then on a constructive note: don't solve this for "your program", but solve it for the input device. Make the joystick fire more deltas per second, based on how long it's been held (relatively simple with an arduino, etc), and the problem of "how to do this in java" disappears, because you now have a univeral solution for all programs on all operating systems. – Mike 'Pomax' Kamermans Feb 03 '13 at 14:30
  • I think Mike is right, that you probably don't want to solve this for your programme but for all programmes. By all means, carry on prototyping in Prototype but you'll eventually want to intercept the input as it comes in from hardware and modify the cursor position at the driver level. – hcarver Feb 04 '13 at 11:36
  • Thanks Mike- that's a good suggestion. Just wondering if you've seen or got any examples you can link me to around the arduino firing deltas option? – samjewell May 06 '13 at 09:58

1 Answers1

0

as Carl suggested, I believe the best answer short of making the mouse actually have this behavior, is some sort of jumping behavior that will get the mouse fairly close to where you need to go, then use the joystick from there.

I happen to know that a program called AutoItv3 can do this sort of thing. You could set it up to recognize special hotkeys, then have that hotkey move the mouse to whatever region you wish.

Commands useful for this are HotKeySet, MouseMove, and Func/EndFunc.

Drifter64
  • 1,103
  • 3
  • 11
  • 30