Custom Input Devices: How does it all work?

Topics about the general development of Orxonox.

Moderator: PPS-Leaders

georgr
Noxonian Grollknom
Posts: 8
Joined: Mon Oct 07, 2013 1:20 pm

Custom Input Devices: How does it all work?

Post by georgr » Mon Oct 07, 2013 1:55 pm

Greetings everyone,

I'm in this semester's Orxonox PPS and decided to try and implement a WiiMote interface. I'm now stuck trying to figure out how exactly input devices are managed, where data is collected, passed on and mapped to game actions. So far, I've gathered the following (please correct any mistaken impressions):

-Input is collected by (extended) InputDevice instances representing an input device each; these interface with X Window Manager directly
-The collected input is somehow passed to the InputManager, from where/bz which it is passed to the various components that can accept input.
(These are just the things I gathered from the Input Wiki page)

My questions now would be:
-Is there a clean way for me to define a custom InputDevice-inheriting class for my WiiMote that can interface with the InputManager as well as the WiiC library (OIS has rudimentary WiiMote support, but not enough for what I'm trying to do) and act as sort of a hybrid between the mouse and controller device classes (using the IR functionality to act like a mouse for steering the craft and the buttons for controlling things like weapons, speed etc)?
-How/where would I code the key mappings for the WiiMote?
-How is the input data actually passed between these classes, and what would I have to change to accomodate the WiiMote?
-Where/how does the game select between different input devices? I wouldn't want to have mouse input interfering with my WiiMote input, for example, so it would be nice to be able to have kind of a "WiiMote Option" where only WiiMote and keyboard commands are accepted. I've noticed that in the game, the only options in the input menu are regarding keyboard and mouse input...
-How do the standard OIS play into the whole thing? What parts are handled by them, and what's done by the original orxonox code?

The bottom line is really that I'm looking for a run-down of the whole input data flow, all these classes referencing each other and some macro magic to top it all off are really making my head spin.

Thanks in advance for your help,

Georg

User avatar
x3n
Baron Vladimir Harkonnen
Posts: 810
Joined: Mon Oct 30, 2006 5:40 pm
Contact:

Re: Custom Input Devices: How does it all work?

Post by x3n » Mon Oct 07, 2013 9:10 pm

The input system was designed and implemented by Reto but I'm not sure if he's still reading this forum.

I cannot answer all your questions off the top of my head but I'll try to find some answers soon.

So far I can tell you only a few things:
  • We use OIS as an external library for input handling. OIS handles everything from the moment when you press a button up to the point where we (Orxonox) receive a callback with the input event. This includes all OS-dependent stuff and some abstraction layers (therefore all input devices behave the same from our point ov view).
  • OIS is included in our source repository (src/external/ois). I don't know which version this is, but if you need a more recent version to work with the WiiMote you have to upgrade it and probably adjust some code in Orxonox.
  • OIS has a list of keys. This includes keyboard keys but also mouse, joystick, gamepad and (virtual) wiimote keys.
  • OIS/Orxonox knows different kinds of events. I'm not sure where to draw the line between OIS and Orxonox without looking into the code. There are different types of events, I think we distinguish between buttons and axes. A button has a binary state (pressed or not) and triggers events when pressed or released. An axis has a floating point state between 0 and 1 (or maybe -1 and 1) and triggers an event when moved. You can imagine a mouse or a joystick as two axes. A slider on a gamepad is one axis.
  • Events (and the state of the corresponding button or axis) are sent via callbacks from OIS to Orxonox.
  • Orxonox maintains a list of so called key-bindings. A key-binding is a console-command which is bound to a button or axis. If the button or axis triggers an event, the console command is executed.
  • If a console command is bound to a button, you can bind it to different events: press, release, or hold. Depending on this, the console command is either executed when you press the button, release it, or when you hold it.
  • If a console command is bound to an axis, every movement of the axis executes the command plus the state of the axis is passed to the command as an argument.
  • I could tell you more about console commands (I implemented them) but I think it's out of scope of your project. All you have to know is that a console command executes a function in C++ with some arguments. Console commands can be typed into the console (hence the name) or bound to a key (key-binding).
  • The input framework in Orxonox (located in src/libraries/core/input) acts as the "glue" between OIS and console-commands. It's responsibility is to recieve input events from OIS and pass them to the correct console command, based on a list of key-bindings.
If you start, it's probably a good idea to think about how you want to map the WiiMote events to the concept of buttons and axes. If you know how you want to do this, figure out how you can use OIS to react upon WiiMote events. Then try to receive these events in Orxonox. First you can test it with some debug output, later you may bind a console-command to one of your WiiMote events.
Fabian 'x3n' Landau, Orxonox developer

The Jo
General DuGalle
Posts: 121
Joined: Mon Mar 01, 2010 7:43 pm

Re: Custom Input Devices: How does it all work?

Post by The Jo » Tue Oct 08, 2013 11:05 am

About the general goal:
Do you have an idea how to steer a spaceship with a wiimote as input device?
The Problem is, that we use two input devices to steer a spaceship.
The mouse to aim and select weapons (left click, right click and middle click) and a ton of keys on a keyboard.
E.g. W to accelerate to the front and A,S,D to accelerate to the left, back and right. The R and F keys accelerate up and down.
The space bar creates boost, and with Q/E you rotate to the left/ to the right. When pressing T a rocket is launched.
There are also special functions like changing the camera when pressing C, decoupling aim from flight direction, when pressing tab, free camera mode when pressing Control and the ESC key to call the menu.
Besides if you press the F1 to F5 some overlays/ in game menus appear.
Here the quest menu and probably the pickup menu are a must have.
-----------------------------------------------------------------
With this post I do not want you to give up, but try your best.
Besides the ESC key, all other special functions can be omitted.
The mouse input is replaced by the location the wiimote is pointing.
Accerlerating to the left/ right is not needed, up and down acceleration might also be omitted. I consider ESC, boost and the weapons as most important features.
Fail. Fail again. Fail better.

User avatar
x3n
Baron Vladimir Harkonnen
Posts: 810
Joined: Mon Oct 30, 2006 5:40 pm
Contact:

Re: Custom Input Devices: How does it all work?

Post by x3n » Tue Oct 08, 2013 5:41 pm

An input device doesn't have to cover all features. You can play Orxonox with a gamepad which acts like a combination of mouse and keyboard, but with less buttons. If you need more buttons, you can still use the keyboard.
The same holds for the WiiMote. Just use the keyboard if necessary. After all, Orxonox is a PC game and not a Wii one. It's still cool if we can use the WiiMote though, but it will of course never be enough to use all features.
Fabian 'x3n' Landau, Orxonox developer

georgr
Noxonian Grollknom
Posts: 8
Joined: Mon Oct 07, 2013 1:20 pm

Re: Custom Input Devices: How does it all work?

Post by georgr » Sat Oct 12, 2013 3:03 pm

Well, for the control scheme I've already thought of a few options:
-IR Tracking acts like a mouse for steering - this necesssitates an IR bar, but it's worth the trouble IMO since accelerometers are inherently unprecise.
-A and B fire primary and secondary weapons, respectively
-the accelerometer is used to control roll, but with a button-like behaviour instead of continuous measuring, e.g. a wiimote roll of more than X (a suitable value will have to be determined) has the same effect as pressing Q/W on the keyboard
-The boost button is the Z button of the Nunchuck
-For throttle control, you press C on the Nunchuck and move the joystick up/down to increase/decrease throttle
-For functions used in less stressful (i.e. non-combat) situations like the quest overlays etc, the plus/minus/1/2 buttons can be mapped
-Maybe fire rockets with D-pad down? This isn't very elegant, but it's either 2 easily accessible lasers or 1 laser and 1 rocket...

I'm just wondering how I can get the WiiCPP library to somehow interact with OIS meaningfully, seeing as OIS seems to be geared towards OS-generated input events (or am I wrong with this assumption? I could not for the life of me find any documentation on OIS...). I've already got the example program to run and register wiimotes on my laptop, so on that end, it's looking good.

User avatar
x3n
Baron Vladimir Harkonnen
Posts: 810
Joined: Mon Oct 30, 2006 5:40 pm
Contact:

Re: Custom Input Devices: How does it all work?

Post by x3n » Sat Oct 12, 2013 4:13 pm

OIS is indeed designed to use input events on the OS-level. And I guess your WiiMote will produces those events if you install an appropriate driver. I don't know if you need WiiCpp for that...

The latest (well, it's from 2010) release of OIS (1.3) contains sources for the WiiMote on Windows. See the project homepage: http://sourceforge.net/projects/wgois/
Those sources are not included in Orxonox so far. You may have to update OIS to v1.3.

If your target plattform is not Windows, then however I don't know if you can achieve your goal with OIS...
Fabian 'x3n' Landau, Orxonox developer

georgr
Noxonian Grollknom
Posts: 8
Joined: Mon Oct 07, 2013 1:20 pm

Re: Custom Input Devices: How does it all work?

Post by georgr » Mon Oct 14, 2013 7:11 pm

Well, the only reference to wiimotes I could find in OIS' (virtually non-existent) documentation stated that IR tracking wasn't implemented, and without that defining feature, the wiimote (IMO) doesn't have enough ways to input things to be a suitable controller for orxonox. Maybe bypassing OIS altogether and writing my own separate input module for the WiiMote would be the way to go? The WiiCpp library allows for some pretty easy no-fuss input handling (it's also RMS-approved, being licensed under the GNU GPL), so if there's a way to sort of emulate the events OIS generates and pass them to the orxonox input handler, hooking the wiimote up to Orxonox would not be too difficult. Going through OS layers seems unnecessarily tedious to me, considering most wiimote libraries I've seen are third-party projects that don't rely on any system calls apart from bluetooth communication, which it handles with libbluetooth-dev.

Also, I'm definitely not considering Windows as my target platform seeing as actually getting Orxonox to run on it seems to be a task few have accomplished yet - two of my colleagues who are in this semester's PPS tried it and they both gave up eventually. I think I'll just stick to Linux.

User avatar
x3n
Baron Vladimir Harkonnen
Posts: 810
Joined: Mon Oct 30, 2006 5:40 pm
Contact:

Re: Custom Input Devices: How does it all work?

Post by x3n » Mon Oct 14, 2013 8:17 pm

In this case you're probably right, it's better to bypass OIS and use WiiCpp. It shouldn't be too hard to inject some events into Orxonox' input system. Just look at how OIS events are handled, then do the same with your WiiMote events. Just try to find the part of the code which "translates" OIS events into Orxonox events. If you need some hints, keep asking. But I'd have to look into the code as well.

Regarding Windows: If you or someone else has trouble building it on Windows, please post your problems in this forum. Even if you don't really care if you use Windows or Linux; but every feedback helps us improving the documentation.
Without feedback, I have no clue what the problems are... because I can build Orxonox with both MinGW and Visual Studio on every Windows machine I own (including virutal machines) without any issues. But maybe I simply forgot to add an important detail to the documentation or maybe I use an old version of some tool and the new versions don't work anymore...
Fabian 'x3n' Landau, Orxonox developer

georgr
Noxonian Grollknom
Posts: 8
Joined: Mon Oct 07, 2013 1:20 pm

Re: Custom Input Devices: How does it all work?

Post by georgr » Tue Oct 15, 2013 8:28 pm

Yeah, that's what we figured in the last PPS session too. From the way it looks, I'm just gonna be pushing hacked together mouse events on the InputManager's stack and doing something similarly ugly with button events, although I haven't been able to find out exactly where/how those are handled yet.

About the Windows thing: I haven't tried it myself, but if I remember correctly, the people who had trouble already got stuck at the CMake part of the build process (as in, they couldn't get CMake on their machines)... I'll let them know to post their problems here, although I'm certain it was nothing that wouldn't be google-able. I'll also try your suggestions from here to get Orxonox to build on my Ubuntu machine tomorrow and report back with my results.

Thanks for all the help, I'll let you know if I need some more info!

smerkli
Human Space Navy Lieutenant
Posts: 20
Joined: Mon Mar 01, 2010 7:28 pm

Re: Custom Input Devices: How does it all work?

Post by smerkli » Sun Oct 20, 2013 4:38 pm

@ x3n: we wondered whether we can have a Singleton or something that simply sits
around and does the calls into orxonox's input system instead of the OIS code. I imagine something like a singleton that's being ticked/polled every x milliseconds and then calls the InputState's mouseMoved function to emulate something like OIS does.

Any thoughts on this approach?

User avatar
x3n
Baron Vladimir Harkonnen
Posts: 810
Joined: Mon Oct 30, 2006 5:40 pm
Contact:

Re: Custom Input Devices: How does it all work?

Post by x3n » Sun Oct 20, 2013 8:17 pm

Well, of course you can have a singleton, you can have anything, you're developers. :)

The question is more like "Is a singleton a suitable solution to our problem" and "does it fit into the existing design". On a side note: try to not use singletons if possible. But before you start thinking about the design, think about responsibilities and behavior.

What needs to be done to create input events from WiiMote actions?
  • Do you need an instance which wraps the driver (or WiiCpp)? Is there only one driver? Maybe that could be a singleton. Maybe.
  • Do you need an instance which represents the WiiMote device? Is there only one? Or maybe multiple? Can you guarantee that there's ever only one such device connected? Probably not. So that's not gona be a singleton.
  • Anything else?
Try to figure out what really needs to be done and how these responsibilites could be implemented in one or multiple classes.

Now look at it from the other side. What do we already have in our input system? For instance there's InputManager, a singleton. It has a list of InputDevice instances. When I look at InputDevice, I see this function:

Code: Select all

        //! Updates the device which should in turn distribute events
        virtual void update(const Clock& time) = 0;
Whoops. That reads a lot like your suggestions, doesn't it? InputDevice is the base class of Mouse, Keyboard and JoyStick. There can be multiple instances of each type.

Maybe all you have to do is to create a new subclass for the WiiMote and put it into the list of devices in InputManager? (That's not a rhetorical question by the way, I really don't know)
Fabian 'x3n' Landau, Orxonox developer

User avatar
beni
Baron Vladimir Harkonnen
Posts: 949
Joined: Tue Oct 03, 2006 9:15 am
Location: Zurich
Contact:

Re: Custom Input Devices: How does it all work?

Post by beni » Tue Oct 22, 2013 4:33 pm

x3n is pretty much right. When you look at our input devices (Mouse, Keyboard etc.) they all inherit from InputDeviceTemplated. This is because this class has already OIS support built in. A call from the InputManager to the InputDevice's update method will call OIS. OIS will then spawn events that are handed back to the InputDeviceTemplated via mouseMoved and similar functions. The InputDevice will then create InputStates which are then again used by the InputManager.

So the call stack looks kind of like this:

... -> InputManager -> InputDeviceTemplated -> OIS -> InputDeviceTemplated (new InputState) -> InputManager -> ...

Since the WiiMote will not use OIS you will have to create the InputStates without the help of OIS events and use the class InputDevice instead of InputDeviceTemplated.

You will then get a call stack like this:

... -> InputManager -> InputDevice -> WiiMoteCode -> InputDevice (new InputState) -> InputManager -> ...

Obviously you will have a WiiMote class that inherits from InputDevice and implements the update method.

Also how about looking at this (Ogre Wiki article on how to use OIS)?

Or this (OIS wrapper to facilitate access to the library)?

OR, if you want to be very bold, have a look at this!

Later on you will need to map the InputStates to Keybindings. I don't know how WiiMote output looks like, but I guess looking at the code that binds the Joystick-Analog-Sticks to keys will help figuring out how WiiMote output will map to our ingame events.
"I'm Commander Shepard and this is my favorite forum on the internet."

georgr
Noxonian Grollknom
Posts: 8
Joined: Mon Oct 07, 2013 1:20 pm

Re: Custom Input Devices: How does it all work?

Post by georgr » Mon Oct 28, 2013 3:34 pm

Thanks for all the help everyone! I have heeded your advice and have now managed to make a dummy WiiMote class (see my code branch) which inherits from InputDevice and doesn't yet interface with an actual wiimote, but is registered in the InputManager's device list and proceeds to output insulting messages to the console. Next week I'll give connecting it to the actual wiimote a try.

User avatar
beni
Baron Vladimir Harkonnen
Posts: 949
Joined: Tue Oct 03, 2006 9:15 am
Location: Zurich
Contact:

Re: Custom Input Devices: How does it all work?

Post by beni » Mon Oct 28, 2013 5:58 pm

You've made some good progress with the understanding of the InputSystem. I'm looking forward to see how the interfacing with the WiiMote will go next week.

If you're able to understand the Inputsystem better, it's definitely a good idea to document your fidings about the Inputsystem overall. Improving the documentation (rather in the Wiki than the code) will help others who will look at the Inputsystem later.
"I'm Commander Shepard and this is my favorite forum on the internet."

User avatar
x3n
Baron Vladimir Harkonnen
Posts: 810
Joined: Mon Oct 30, 2006 5:40 pm
Contact:

Re: Custom Input Devices: How does it all work?

Post by x3n » Mon Oct 28, 2013 7:51 pm

Actually I prefer to put documentation into the code instead of the wiki. It's less likely to get out of date if you put it in the code. It's also the first place where a real developer looks. ;)

Nice to see that you're project makes some progress.
[x] created a class
[x] created insulting messages
[ ] working wiimote input

I'd say you're 67% done :beerchug:
Fabian 'x3n' Landau, Orxonox developer

Post Reply

Who is online

Users browsing this forum: No registered users and 6 guests