FreeVR: Virtual Reality Integration Library
FreeVR
Tutorials
User Guide
Programming
Functions

FreeVR

TUTORIALS

DOWNLOADS

GUIDES
    Administrator
    User
    Programming
    Function List
    Library Dev
    Socket Interface

MAN PAGES


All materials
Copyright © 2024
William R. Sherman

Manpage of WIIMOTE

WIIMOTE

Section: FreeVR Usage (7fv)
Updated: 5 December 2013
Index Return to Main Contents

 

NAME

Wiimote — A How-to document for interfacing Nintendo Wii™ remotes with FreeVR  

DESCRIPTION

The Nintendo Wii™ remote, frequently referred to as a "Wiimote" has been a popular input device for virtual reality enthusiasts due to it's low-cost, rich input features, and wireless connectivity.

The wireless connectivity is handled through the Bluetooth technology standard. Part of FreeVR's design constraints is to minimize the number of external requirements, and at least for now, Bluetooth is not included as part of FreeVR's features. Therefore, other, indirect mechanisms must be used to integrate Wiimote controllers into FreeVR, each of which is essentially an input data server, though one ("CWiid") interfaces as a standard X11 input.

The three interfaces are:

CWiid package with wminput
VRPN (the Virtual Reality Peripheral Network)
Vrui's VRDataDaemon

NOTE: Presently all the methods presented are for use with the Linux operating system. As methods are ascertained for interfacing on other operating systems, this manpage will be augmented. Also of note is that there is a project ("XWiimote") to integrate Nintendo Wii™ remotes directly into the Linux kernel. This is part of the Linux 3.x distribution effort.

In all cases, the computer must have a Bluetooth adaptor to communicate with the device.  

HOWTO

Each of the following subsections provide instructions on how each of the interfaces listed above can be used to accomplish Wiimote interaction with FreeVR.

Before delving into specific methods of the three interfaces, verify that the low-level Bluetooth communication with the device is operational.

On Linux this can be accomplished with the "hcitool" — specifically the "scan" command:

    (press the 1 and 2 buttons on your Wiimote)
    % hcitool scan
    Scanning ...
        00:24:1E:7A:CC:2D       Nintendo RVL-CNT-01
 

CWiid / wminput

The CWiid package is a Wii™ remote "daemon" library written in C. The library provides a convenient API for interfacing with Wiimote devices, and the CWiid package includes the wminput daemon which converts Wiimote events into Linux event device system (aka "evdev", or in FreeVR parlance "EVIO") using the Linux "uinput" kernel module.

So wminput is the actual program that one executes to link the Wiimote to the uinput system. Usually, this will have to be run with superuser authority. And furthermore, doing so will also set the permissions of the "/dev/input/event<N>" device to be readable by root only, so proper accommodations must be made — generally changing the permissions on the input device.

    # /usr/local/lib/cwiid/wminput -c /usr/local/lib/cwiid/config/buttons
    Put Wiimote in discoverable mode now (press 1+2)...
    Ready.
    # chmod 666 /dev/input/event<N>

NOTE: by default, the wminput program does not look in the local directory to find a file, so when giving a relative path, the "./" must be explicitly specified.

Once "wminput" is configured and running, you can test the inputs using the "eviotest" program that comes with the FreeVR distribution.

    % ./eviotest /dev/input/event<N>
    [...]
             epttn12kdtt
    buttons: 00000000000

NOTE: the characters above the input values are the last character of each name.

The accompanying lswm tool can be executed first in order to list all the Wiimotes currently in discoverable mode. (Which really can also be done with the "hcitool scan" operation.)

    % lswm
    Put Wiimotes in discoverable mode now (press 1+2)...
    00:24:1E:7A:CC:2D

Configuration File
There is a "wminput" configuration file required to select what buttons are mapped and in what order. Mappings are to any input types as listed in:
    /usr/include/linux/input.h

For example:

    % cat /usr/local/lib/cwiid/config/buttons
    # Button mappings:
    Wiimote.A       = BTN_A
    Wiimote.B       = BTN_B
    Wiimote.Up      = KEY_UP
    Wiimote.Down    = KEY_DOWN
    Wiimote.Left    = KEY_LEFT
    Wiimote.Right   = KEY_RIGHT
    Wiimote.1       = KEY_PROG1
    Wiimote.2       = KEY_PROG2

    Plugin.acc.X    = ABS_X
    Plugin.acc.Y    = -ABS_Y

For configuration on the FreeVR side, there is a difference as to whether a Wiimote button was mapped to a "BTN" or a "KEY". For "wminput" inputs mapped to "KEY" mappings, FreeVR configuration also uses "key":

    control "print_struct" = "2switch(key[Home])";
    input "2switch[1]" = "2switch(key[Prog1])";

For "wminputs" mapped as "BTN" type inputs, there is a choice of how to indicate this on the FreeVR side. Buttons can be thought of as special "key" inputs, using the string "Btn:" to indicate such. Thus, both of the following will work:

    input "2switch[2]" = "2switch(button[A])";
    input "2switch[3]" = "2switch(key[Btn:B])";

And for valuators:

    input "wii-roll" = "valuator(abs[X])";
    input "wii-elev" = "valuator(abs[Y])"; 

Note however that the only "valuators" currently available through the "wminput" program are the accelerometers. The joystick on the Nunchuk is not available as a valuator — there is a plugin to map the joystick to buttons, but not for getting the actual valuator value. This is a major shortcoming of the CWiid/wminput system.

Troubleshooting
There are a handful of common problems which can be easily resolved with the following instructions.
1)
You get the error — "ImportError: No module named cwiid".
If you see this error, this means that the "CWiid package was compiled with the Python option. Using the Python option is fine, it just requires that the PYTHONPATH environment variable be set accordingly to point to the location of the "cwiid.so" shared object:
    # export PYTHONPATH=<...>/python/build/lib.linux-x86_64-2.6
2)
Your Wiimote events are generating inputs to the X11 input system. Depending on your Linux configuration, initiating new input devices will sometimes link them to the X11 input system. The "xinput" command can be used to verify and fix this problem.

First, find it's input id:

    % xinput list --short | grep Wiimote
         Nintendo Wiimote            id=10   [slave  keyboard (3)]

The next step is determine the property number for the "Device Enabled property of the input device with the id above (e.g. "10" in this example):

    % xinput list-props 10 | grep "Device Enabled"
            Device Enabled (117):   1

With the id ("10") and enable/disable property code ("117"), the device's effect on the X11 input system can now be turned off. The command to change a property also takes arguments for the number of bits of the datum as well as the value. As the enable/disable flag only requires one byte (which is in effect the minimum), the command is (along with verification):

    % xinput set-int-prop 10 117 8 0
    % xinput list-props 10 | grep "Device Enabled"
        Device Enabled (117):   0
 

VRPN

The VRPN (Virtual Reality Peripheral Network) is an input device (really an I/O device) server system that can interface with a wide variety of devices, old and new. The Nintendo Wiimote is one of the many devices handled. And as FreeVR can interface directly with VRPN, all that is needed is to install VRPN and configure the "WiiMote" interface.

VRPN is not generally included with Linux distributions, but it is easy to download and compile.

Enabling the basic "WiiMote" input is straightforward:

    % cat wiimote_vrpn.cfg
    vrpn_WiiMote           WiiMote0 1 0 0 1
    % vrpn_server -f wiimote_vrpn.cfg

There is also a tracking form of VRPN interface with the WiiMote which involves the use of the IR sensor information along with some post-processing (all handled within VRPN):

    % cat wiimote_vrpn.cfg
    vrpn_WiiMote              WiiMote0 1 1 1 1
    vrpn_Tracker_WiimoteHead  Tracker0 WiiMote0@localhost
    % vrpn_server -f wiimote_vrpn.cfg
NOTE: that the middle two flags ("useMotionSensing" and "useIR") must be enabled to create tracking output.

Here are the VRPN configuration arguments for the two input types:

    for vrpn_WiiMote:
        1) name_of_this_device (string)
        2) Player number (int)
        3) Use motion Sensing (bool/int) — from the base Wiimote, not motion sensor   
        4) Use IR tracking (bool/int)
        5) Reorder the buttons (bool/int)
        6) [optional] Bluetooth address — provided in all uppercase with colons

    for vrpn_Tracker_WiimoteHead
        1) name_of_this_device (string)
        2) name_of_vrpn_WiiMote_device (string)
        3) [optional] min_update_rate (default=60) (float) [Hz]
        4) [optional] led_distance (default=0.205) (float) [meters]

On the FreeVR side, these can be mapped into inputs with configuration settings similar to:
    input "2switch[A]" = "2switch(WiiMote0:button[1])";
    input "2switch[B]" = "2switch(WiiMote0:button[2])";
    input "2switch[3]" = "2switch(WiiMote0:button[3])";

    input "val[x]" = "Valuator(WiiMote0:analog[ 1])";   # roll/twist
    input "val[y]" = "Valuator(WiiMote0:analog[-2])";   # pitch/elevation
    input "val[u]" = "Valuator(WiiMote0:analog[ 3])";   # right-side-upidness
    input "val[b]" = "Valuator(WiiMote0:analog[ 0])";   # battery level

    input "wand2" = "6sensor(Tracker0:tracker[0])";

NOTE: Analog values 1 and 3 are specifically the ...  

Vrui's VRDeviceDaemon

The Vrui "VRDeviceDaemon" server can handle a variety of input devices, much like VRPN. And the Nintendo Wii™ remote is one input device it can handle.

In fact it is fairly straightforward. The only real requirement is that the Vrui system be compiled with the Bluetooth feature enabled.

Once Vrui is compiled, a "VRDevices.cfg" configuration file for the VRDeviceDaemon program must be created. To collect button and valuator inputs only (valuators with an attached Nunchuk of course), use this configuration (replacing the hostname with the correct value):

section "<hostname>"
    section DeviceManager
    deviceNames (Wiimote1)
    section Wiimote1
    deviceType WiimoteTracker

    # Set this to the Bluetooth ID of the Wiimote
    devicename "00:24:1E:7A:CC:2D"

    # Set the LED pattern for this Wiimote (any 4-bit value)
    ledMask 1

    # Disable motion tracking using the Wiimote's camera
    enableTracker false
    endsection
    endsection
endsection

and then run the Vrui VRDeviceDaemon:

    % bin/VRDeviceDaemon
    VRDeviceDaemon: Reading configuration file
    VRDeviceDaemon: Initializing device manager
    VRDeviceManager: Loading device Wiimote1 of type WiimoteTracker
    WiimoteTracker: Connecting to first compatible Bluetooth device.
    WiimoteTracker: Please press buttons 1 and 2 to initiate connection... done
    WiimoteTracker: Connected wiimote's battery level is 145%
    VRDeviceManager: Managing 0 trackers, 13 buttons, 2 valuators
    VRDeviceManager: Managing 0 virtual devices
    VRDeviceDaemon: Initializing device server
    VRDeviceServer: Waiting for client connection

In another shell, the inputs can be tested with the FreeVR "vruiddtest" program:

    % ./vruiddtest

For position tracking, there are a handful of additional options that must be specified. However, position tracking with the Vrui system only works with physical LED configurations that have four LED markers rather than the customary two. So this system does not work with the standard Wii sensor bar.

The additional configuration options are:

    cameraCenter (512, 384)
    cameraFocalLength 1280

    targetPoints ((-2.0, 0.0, 0.0), (0.0, -1.0, 2.0), (2.0, 0.0, 0.0), (0.0, -1.0, -2.0))
    targetTransformation identity

    homeTransform identity
 

BUGS

For the wminput method, in some configurations the
"event<N>" device is not readable without superuser permissions, requiring a permission change.
Especially for the VRPN mothod, when using the Wiimote
as a 6-dof position tracker, the scale factor will need to be adjusted, and FreeVR does not yet provide this option in the VRPN interface.
 

TODO

Consider intregrating a Wiimote interface directly into FreeVR.
Note that this would then require all FreeVR applications to be linked with the Bluetooth library.
Consider writing enhancements to the "wminput" program. Most
importantly, to handle joystick valuator values of the Nunchuk, but also other small by handy improvements.
 

SEE ALSO

xinput(1), wminput(1), eviotest(1fv)

The sample FreeVR configuration file for VRPN:

$FREEVR_HOME/etc/rc_sample_vrpn

Web sites:

http://www.freevr.org
https://en.wikipedia.org/wiki/Wii_Remote
https://wiki.archlinux.org/index.php/Wiimote


Video:

"Head Tracking for Desktop VR Displays using the WiiRemote" by Johnny Lee:
    https://www.youtube.com/watch?v=Jd3-eiid-Uw


 

COPYRIGHT

Copyright 2024, Bill Sherman, All rights reserved.


 

Index

NAME
DESCRIPTION
HOWTO
CWiid / wminput
VRPN
Vrui's VRDeviceDaemon
BUGS
TODO
SEE ALSO
COPYRIGHT

This document was created by man2html, using the manual pages.
Time: 21:57:57 GMT, March 04, 2024