the robotcowboy unit daemon
a device event to Open Sound Control bridge daemon and associated tools
Copyright (c) Dan Wilcox 2007 - 2014
The rc-unitd package contains the following parts:
- rc-unitd - device event daemon
- rc-unit-notifier - insert/removal notification tool
- lsjs - joystick info tool
This group of tools allows any OSC-capable program to receive joystick event data aka button presses, axis movements, etc. Specific joysticks can be mapped by name to specific OSC send addresses and button, axis, etc ids can be remapped or ignored. A notification tool can control the running daemon.
A udev rules set is provided for GNU/Linux to enable automatic notification when devices are plugged in.
These tools are developed for the robotcowboy project, a wearable computer music system using Pure Data in GNU/Linux. See http://robotcowboy.com
Here's a quick start to build and install for Ubuntu/Debian on the command line:
sudo apt-get install libsdl-dev liblo-dev git clone git://github.com/danomatika/rc-unitd.git cd rc-unitd ./configure make sudo make install sudo cp data/85-rc-unitd.rules /etc/udev/rules.d
If everything finished successfully, you're good to go.
The following libraries are required:
- liblo (lightweight osc)
Install the required development versions of the libraries using your distro's package manager.
For Debian/Ubuntu, you can use use
apt-get on the command line:
sudo apt-get libsdl-dev liblo-dev
- install the Macports binary and setup the Macports environment
- go to the Terminal and install the libs:
sudo port install libsdl liblo
If you use the default Macports install location of
/opt/local, you will need to set the Macports include and lib dirs before running ./configure:
export CPPFLAGS=-I/opt/local/include && export LDFLAGS=-L/opt/local/lib
- install the Homebrew environment
- go to the Terminal and install the libs:
brew install sdl liblo
Windows support should work, but hasn't been tested. I'd recommend installing binary versions of the required libraries and building rc-unitd in MiniGW/Cygwin.
As this is an GNU autotools project, simply run the following on the command line:
./configure make sudo make install
This readme, example config files, and the pd library are also installed to your doc dir, something like
By default, the configure script installs to
/usr/local. To change this behavior, specify a new dir before building the project:
If using Macports on Mac OS X, it is recommended to use the Macports default prefix of
All applications have a full help usage printout, use -h or --help.
Starts device daemon with the default settings.
% rc-unitd config_file.xml
Starts device daemon using the given config file.
The config file sets the OSC connection information as well as device to OSC address mappings. Look at the
example_config.xml file installed to the doc folder or in the
data folder of the source distribution for details.
You can also specify values on the command line which override values in the config file:
-i, --ip IP address to send to; default is '127.0.0.1' -p, --port Port to send to; default is '8880' --listening_port Listening port; default is '7770' -e, --events Print events; default is '0' -s, --sleep Sleep time in usecs; default is '1000'
Note: Enabling event printing is useful when debugging:
% rc-unitd -e 1 ... /js2 "Saitek P990 Dual Analog Pad" Axis: 0 Value: 32767 /js2 "Saitek P990 Dual Analog Pad" Axis: 1 Value: -32768 /js2 "Saitek P990 Dual Analog Pad" Axis: 2 Value: -32768 /js2 "Saitek P990 Dual Analog Pad" Axis: 3 Value: -32768 /js2 "Saitek P990 Dual Analog Pad" Button: 8 State: 1 /js2 "Saitek P990 Dual Analog Pad" Button: 9 State: 1 /js2 "Saitek P990 Dual Analog Pad" Button: 10 State: 1 /js2 "Saitek P990 Dual Analog Pad" Button: 11 State: 1 /js2 "Saitek P990 Dual Analog Pad" Button: 0 State: 1 /js2 "Saitek P990 Dual Analog Pad" Button: 3 State: 1 /js2 "Saitek P990 Dual Analog Pad" Button: 0 State: 0 /js2 "Saitek P990 Dual Analog Pad" Button: 3 State: 0 /js2 "Saitek P990 Dual Analog Pad" Button: 0 State: 1 /js2 "Saitek P990 Dual Analog Pad" Button: 3 State: 1 /js2 "Saitek P990 Dual Analog Pad" Button: 0 State: 0 /js2 "Saitek P990 Dual Analog Pad" Button: 3 State: 0 /js2 "Saitek P990 Dual Analog Pad" Button: 3 State: 1 /js2 "Saitek P990 Dual Analog Pad" Button: 3 State: 0 /js2 "Saitek P990 Dual Analog Pad" Button: 0 State: 1
See the Pure Data patches installed in
pd installed to the doc folder or the
data/pd folder of the source distribution for info on how to receive events from rc-unitd, although any software that can receive Open Sound Control messages will work.
rc-unitd streams device event information in the following OSC address format:
/rc-unitd/devices/DEVICE_NAME/INPUT_TYPE ID VALUE
- DEVICE_NAME is the mapped name to the device as specified in the config file, otherwise it is "js#" with # being the current device id
INPUT_TYPE can be
hatdepending on the control layout of your joystick/gamepad.
- ID is the id number for the control (aka button 1, axis 2, etc); these are likely different from device to device
VALUE is the current value of the control:
- button state values are 1 or 0 for pressed & released
- all other controls have a value from -32767 to 32767
/rc-unitd/devices/js2/button 2 1 /rc-unitd/devices/js2/button 2 0 /rc-unitd/devices/js2/axis 0 32767
rc-unitd also sends status notification messages:
/rc-unitd/notifications/startup /rc-unitd/notifications/ready /rc-unitd/notifications/open devtype /rc-unitd/notifications/close devtype /rc-unitd/notifications/shutdown
The lsjs tool lists the names of currently plugged in joysticks, which you can then use to create your device mappings.
% lsjs 0 "OSCulator HID 1" 1 "OSCulator HID 2" 2 "Saitek P990 Dual Analog Pad"
You can also print detailed info using the -d or --details flags.
% lsjs -d 0 "OSCulator HID 1" num axes: 4 num buttons: 20 num balls: 0 num hats: 0 1 "OSCulator HID 2" num axes: 4 num buttons: 20 num balls: 0 num hats: 0 2 "Saitek P990 Dual Analog Pad" num axes: 4 num buttons: 14 num balls: 0 num hats: 1
Used to control a running rc-unitd. Can be used to signal device add or removals as well as send a quit command.
A new joystick was added, reload current joysticks:
% rc-unit-notifier -t joystick open
A joystick was removed, reload current joysticks:
% rc-unit-notifier -t joystick close
Tell rc-unitd to shutdown:
% rc-unit-notifier quit
rc-unit-notifier has ip and port setting options similar to rc-unitd:
-i, --ip IP address to send to; default is '127.0.0.1' -p, --port Port to send to; default is '7770' -t, --type Device type to perform the action on (for internal use)
Example, tell rc-unitd running on machine at 10.0.0.100 using port 10100 to shutdown:
% rc-unit-notifier -i 10.0.0.100 -p 10100 quit
There is a udev rule file for Linux installed to the doc dir that can be used to automatically call rc-unit-notifier when a joystick device is plugged/unplugged:
If you want to enable hot plug support, simply copy it to the udev rules folder:
sudo cp data/85-rc-unitd.rules /etc/udev/rules.d
Whenever a joystick device is plugged in or unplugged, rc-unit-notifier is automatically called to send an add or remove event to rc-unitd if it is running.
See the comments in the rules file itself for more info:
Note: This file in generated while running
make, so it will not exist until you build the project.
As rc-unitd & lsjs use SDL, they will not work over a SSH connection and you'll get the following error:
Error: Couldn't initialize SDL: Unable to open a console terminal
Run them from a real terminal on the machine.
A Premake4 script and IDE files can be found in the prj folder. Premake4 can generate the IDE files from a given lua script. Download Premake4 from http://industriousone.com/premake.
Make sure the externals are built by calling the prj/setupbuild script which runs configure and calls make in the externals dir.
You can enable a debug build using:
I develop using an IDE, then update the autotools files when the sources are finished. I run make dist-check to make sure the distributable package can be built successfully.
- add automatic device add/remove support on OSX (via IOKIT)
- update the SDL 2.0 which fixes the above issue as well
- add multicast support
- multiple osc send addresses for event forwarding between multiple machines
- add built in osc -> MIDI and other mapping capability (ala junXion or Osculator)