Velocity-Based Joystick Controller



Click here for a larger image.

Environment: VC6 SP4, NT4 SP3, Win2K

Currently, I am working towards building an omni-directional autonomous mobile robot. Omni-directional refers to a vehicle that could translate (or move) and spin (or rotate) simultaneouly. Just for an example, your car is not an omni-directional vehicle. As part of this ongoing project, I was assigned the job of building an application that could control the robot's motion from a desktop, remotely, rather than using a physical joystick as a child would normally drive his "Remote Toy Car." The application should be able to spit commands for both the modes of action (move and spin), simultaneouly. So, I did one and called it the Joystick Controller. Here is a part of it that is developed as the user interface.

The Joystick Controller is built as a stand-alone subclass that is derived from CStatic. To use this in your application, all that needs to be done is subclass a static control (the placeholder for the joystick control) in the dialog with the provided CJoystickCtrl class. For testing and demonstration purposes, the provided application shows a pie-shaped wedge that moves and rotates (with respect to the center) in the left half of the window. The different modes of action for the joystick are mapped to the various mouse events.

NOTE: ALL THE GENERATED VALUES ARE WITH RESPECT TO THE CENTER OF THE JOYSTICK AND NOT WITH RESPECT TO THE CLIENT AREA OR THE WINDOW AREA.

For a mouse click event in the Stick region (the gradient filled region of figure above):

  • Left Mouse Button Down: Increases the velocity of movement by a value equal to the distance between the mouse click point and the center of the joystick. For generalization purposes, the value is mapped between 0 and 10. The direction of the line from the center of the joystick to the mouse click provides the direction of the movement.
  • Left Mouse Button Up: Brings back the joystick's stick region to the stand-alone mode. In this mode, it spits only zeros.
  • Right Mouse Button Down: Same as that of left mouse button down except that it does not move to the stand-alone mode on the Right Mouse Button Up event.

For a mouse click event in the Spin region (the arced region of the figure above):

  • Left Mouse Button Down: Increates the velocity of rotation by a value equal to the distance between the mouse click point and the point of half the arc-length. Again, for generalization purposes the values are mapped between -10 to +10. The sign of the generated value gives the direction of rotation. Negative for anti-clockwise and positive for clockwise rotation.
  • Left Mouse Button Up: Brings back the joystick's spin region to the stand alone-mode—so spits only zero.
  • Right Mouse Button Down: Same as that of left mouse button down except that it does not move to the stand-alone mode on the Right Mouse Button Up event.

The basic idea of the implementation is that we should be able to issue a rotation command while something is already moving or vise-versa. Moreover, it should be able to issue variable commands based on the desired velocity; in other words, the farther you drive from the center, the faster the dependent object moves.

The demo application (previewed in the picture above) shows a pie-shaped structure (the dependent) in the left half of the window—moving and rotating simulataneously. The speed by which the pie moves or rotates is totally controllable by the joystick on the other half of the window.

Steps to Add This to Your Project

Say, m_Joystick is the object you make for the IDC_JOYSTICK static-object in the dialog box. Add the following line in the InitDialog for a dialog-based application (or in the equivalent funtion in a window-based application):

m_Joystick.SubclassDlgItem(IDC_JOYSTICK, this);

This is all is required to get the joystick to show up on your window. To get the direction of movement, the velocity of movement, and rotation, one can use the following public functions provided as members of the CJoystickCtrl class.

// To get the move direction.
// this is with respect to the center (0, 0) of the joystick
CPoint GetMoveDir();

// To get the rate at which to move
// Is mapped between 0 to 10
int GetMoveRate();

// To get the rate at which to move
// Is mapped between -10 to 10
// Negative value indicates anti-clockwise rotation and
// Positive value indicates clockwise rotation
int GetAngle();
This control can easily be used to control the movement and orientation of moving objects in the real world. At least, for now it is successfully being used to control my ROBOTS.

Downloads

Download demo project - 29 Kb
Download source - 7 Kb