Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

RFC: Joystick API

Huns Valen
Don't PM me here.
Join date: 3 May 2003
Posts: 2,749
11-11-2003 03:23
RFC?
---------------------------------------
An RFC is a Request for Comments. It is patterned loosely after these.


Status of This Memo
---------------------------------------
This memo defines an Experimental Interface for use within LSL. Discussion and suggestions for improvement are requested.


Abstract
---------------------------------------
Joystick support has been suggested in the past, but has received a reception that could be considered lukewarm at best. However, now that Second Life has vehicle support, it is becoming increasingly obvious that relying on a few trappable keys is a clunky and onerous way to control a vehicle, outside a very narrow range of parameters. This is particularly true of ground vehicles, which practically have to be optimized differently for each coursre they run on in order to yield the best results. This can be overcome to a certain degree with clever scripting, but even the most intelligently-planned keyboard control scheme would be hard-pressed to compete with even a mediocre joystick control scheme.

This is a first draft of constants, functions, and an event that we would like to propose. Joystick inputs would be accessed with a joystick() event, with buttons and axes passed in a manner that is (somewhat) consistent with the control() event. There would also be a facility to map joystick axes directly to the linear and angular motors, which should make it exceptionally easy to adapt vehicle scripts to use joysticks.

We are working under the assumption that the joystick inputs would be reported to the LSL VM on the same schedule as the keyboard.


To Be Addressed
---------------------------------------
This early draft does not address D-pad joysticks. It is suggested that, provisionally, the viewer provide an option to map the D-pad to the cursor (arrow) keys. It will also be necessary to add joystick-related constants for llTakeControls() et. al.


Interface Specifics
---------------------------------------
// Constants concerning axes and buttons
JOY_NUM_AXES
JOY_NUM_BUTTONS
JOY_AXIS_MIN
JOY_AXIS_MAX
JOY_AXIS_X
JOY_AXIS_Y
JOY_AXIS_Z // throttle
JOY_AXIS_U // rudder
JOY_AXIS_V // rare
JOY_AXIS_W // not even sure if W exists
JOY_AXIS_ALL // for setting params on all axes

// Hat control and buttons
// Among other things, these are bitmapped in the levels
// and edges parameters in the joystick() event
JOY_HAT_UP
JOY_HAT_DOWN
JOY_HAT_LEFT
JOY_HAT_RIGHT
JOY_BUTTON_1
...
JOY_BUTTON_9

// Constants concerning particular hardware
JOY_VENDOR_ID
JOY_PRODUCT_ID

// Constants concerning axis input smoothing and scaling
JOY_AXIS_SMOOTHING // Average last few inputs against current
JOY_AXIS_SMOOTHING_FACTOR // Same idea as mouse accel
JOY_AXIS_ACCEL_FACTOR // How fast to accelerate across an axis
JOY_AXIS_ACCEL_THRESHOLD // Do not apply acceleration below this speed
JOY_AXIS_NOSCALE // Just return raw axis numbers
JOY_AXIS_SIGNED_100 // Returns range -100 to 99
JOY_AXIS_UNSIGNED_100 // Returns range 0 to 99

// Many joysticks return spurious inputs when the control stick
// is "centered." This sets up a deadzone, such that when the
// joystick is within param / 2 mickeys (or whatever) of
// dead center, the joystick API will say that the stick is at
// dead center.
JOY_AXIS_DEADZONE

// Constants concerning joystick-to-motor mapping.
// Note that multiple axes can be mapped to a singular
// motor. For example, an airplane would map X and Y to the
// angular motor.
JOY_MAP_AXIS_TO_LINEAR_MOTOR
JOY_MAP_AXIS_TO_ANGULAR_MOTOR
JOY_UNMAP_AXIS_TO_LINEAR_MOTOR
JOY_UNMAP_AXIS_TO_ANGULAR_MOTOR
JOY_LINEAR_MAP_FACTOR
JOY_ANGULAR_MAP_FACTOR

// Constants concerning "force feedback" and the like
JOY_HAS_OSCILLATOR

// Reads a single joystick parameter; param = 0 if unneeded
float llGetJoystickParam(paramType, param)

// Sets a single joystick parameter, such as smoothing
// Returns TRUE or FALSE
integer llSetJoystickParam(paramType, param)

// Returns (list)[x, y, throttle, rudder, u, v, w, hatX, hatY]
// i.e. [22.3, -14.57, 78, -12, 0, 0, 0, 1, -1]
list llGetJoystickAxes()

// Returns (rot)<x, y, throttle, rudder>
rotation llGetJoystickControlAxes()

// Returns (rot)<u, v, hatX, hatY>
rotation llGetJoystickAuxAxes()

// Turn on the oscillator (force feedback etc.)
// TRUE if hardware supports this, FALSE if not
integer llActivateJoystickOscillator(integer seconds)

// Joystick event, fired whenever joystick data is returned from the viewer
joystick(key name, integer levels, integer edges, list axes, rotation control, rotation aux)


Example Code
---------------------------------------
// Joystick event
joystick(key name, integer levels, integer edges, list axes, rotation control, rotation aux) {
    // X-axis turns vehicle
    llSetVehicleVectorParam(
        VEHICLE_ANGULAR_MOTOR_DIRECTION,
        <ROTATION_RATE * control.x, 0, ROTATION_RATE/2.0>;);

    // Z-axis controls throttle
    llSetVehicleVectorParam(
        VEHICLE_LINEAR_MOTOR_DIRECTION, <FWD_THRUST * control.z,0,0>;);

    // Button 1 controls
    if((edge & JOY_BUTTON_1) && (level & JOY_BUTTON_1))
        jump();
}

// Using joystick-to-motor mapping (instead of/in addition to joystick() event)
// Set useful joystick axis maps for steering and throttle axes
llSetJoystickParam(JOY_AXIS_SIGNED_100, JOY_AXIS_X);
llSetJoystickParam(JOY_AXIS_UNSIGNED_100, JOY_AXIS_Z);

// Set a deadzone 20 units wide for the X-axis
// (axis in range -10 to +9 will return 0)
llSetJoystickParam(JOY_AXIS_DEADZONE, 20);

// Turn on mapping
llSetJoystickParam(JOY_MAP_AXIS_TO_LINEAR_MOTOR, JOY_AXIS_Z);
llSetJoystickParam(JOY_MAP_AXIS_TO_ANGULAR_MOTOR, JOY_AXIS_X);

// Set mapping factors
llSetJoystickParam(JOY_LINEAR_MAP_FACTOR, 2);
llSetJoystickParam(JOY_ANGULAR_MAP_FACTOR, 1);

// When you are done, unmap the axes with
// JOY_UNMAP_AXIS_TO_LINEAR_MOTOR and
// JOY_UNMAP_AXIS_TO_ANGULAR_MOTOR





Revision History
---------------------------------------
11/11/2003 03:24
Original created by Huns Valen
Bosozoku Kato
insurrectionist midget
Join date: 16 Jun 2003
Posts: 452
11-11-2003 04:54
/clap

Bos
Garoad Kuroda
Prophet of Muppetry
Join date: 5 Sep 2003
Posts: 2,989
11-11-2003 05:03
Heh, neat little RFC.

Joystick support would be really cool.

I haven't used this dusty thing since I played WWIIOL months ago! And it's expensive as hell too!!

I hope you mean analog joysticks and not the atari style digital ones, lol. (Do they even make them anymore?)
Eddie Escher
Builder of things...
Join date: 11 Jul 2003
Posts: 461
11-11-2003 05:54
Yeah, well thought out HV!
I think the addition of analogue and digital joystick/pad would be great!
_____________________
Eddie Escher
...apparently 3 out of 4 people make up 75% of the population here...

Eddie Escher Gadgets & Skins: Hotei and Seacliff
Huns Valen
Don't PM me here.
Join date: 3 May 2003
Posts: 2,749
11-11-2003 06:56
The joystick API I propose would focus on "analogue" joysticks primarily. I have suggested here that a facility be provided to map NES-like D-pad joysticks (I think they are properly called "joypads";) to the cursor keys. Then you'd use the joystick() event to read the button presses and so forth, as with an "analogue" stick.

The distinction (in case anyone doesn't know) is that a joypad only tells you the direction of the control input (i.e. to the left), whereas an analogue stick tells you the magnitude in fairly high precision (i.e. 47% to the left.) This is a HUGE advantage to things like motorcycles and hoverboards and airplanes and speedboats, since any reasonably twisty course is going to require different amounts of throttle and steering for optimal performance. Fixed throttle and turning rates are cumbersome. Adjustable throttle and turning rates can be achieved through clever key combinations, but are not realistic in the heat of a race you expect to complete without having to control your vehicle the same way Steven Hawking composes a sentence.

Believe me, I've tried. I modified a basic hoverboard control script to allow four discreet speeds and turning ratios. Trying to control my vehicle and pilot it around the race course (keeping between the flags) was a chore, especially since it would occasionally fail to trap an arrow key being held down and careen into the water or bonk into the side of a hill. Crossing sim lines while having to turn complicated this quite a bit. You can sort of compensate by tapping the left/right arrows vs. holding them down, but you aren't guaranteed an even interval between control() events, making it haphazard. I even tried having different turn rates maped to left/right vs. shift+left/shift+right, but then you have to choose whether you want good turning performance at high speed OR good turning performance at low speed. If you set it up for a large road course (i.e. the green diamond signs), you have to reverse those settings for a tighter course (i.e. the motorcycle race by the Oak Grove border).

An analogue joystick solves these problems as best as they can possibly be solved. You get to tell your craft exactly how much to turn and exactly how much throttle to apply.
Tiger Crossing
The Prim Maker
Join date: 18 Aug 2003
Posts: 1,560
11-11-2003 07:43
While you're at it, toss in support for the P5 Glove! :D
_____________________
~ Tiger Crossing
~ (Nonsanity)
Huns Valen
Don't PM me here.
Join date: 3 May 2003
Posts: 2,749
11-11-2003 08:48
From: someone
Originally posted by Tiger Crossing
While you're at it, toss in support for the P5 Glove! :D

Reading the thread, it looks like it has standard X/Y/Z axes, plus "buttons." Should look like any other joystick as far as the API is concerned. If the Z-axis is palm pitch, you'd be able to throttle your motorcycle like you would a real one. :)
ZHugh Becquerel
Registered User
Join date: 24 Oct 2003
Posts: 68
11-11-2003 09:53
You could consider adding an abstraction layer in between the logical layer and the hardware.

Concretely, in LSL script you will have a number of abstracted linear input devices, which can be mapped via the SL user-interface, most-likely by the user, to mouse axes, joystick axes, VR helmet sensors, or whatever.

The advantage is that it means that people like me who have a mouse but no joystick can use your scripts because the SL client will automatically map my mouse axes to your linear input devices. Scripts will be very simple.

In code, this would look something like:

Speed = llGetLinearInputDevice(LINEARINPUT_0) * MaxSpeed;
Turn-rate = ( llGetLinearInputDevice(LINEARINPUT_1) * 2 - 1 ) * MaxTurnRate;

(Assuming Linear Input Devices are normalized floats from 0 to 1).

All sensitivity settings and mappings would be carried out by the user via the SL client user-interface ensuring that future programs will be completely future-proof, and current programs really easy to write.

ZHugh
Jack Digeridoo
machinimaniac
Join date: 29 Jul 2003
Posts: 1,170
11-11-2003 14:13
From: someone
Originally posted by Tiger Crossing
While you're at it, toss in support for the P5 Glove! :D


yeah P5 support too!!
Garoad Kuroda
Prophet of Muppetry
Join date: 5 Sep 2003
Posts: 2,989
11-11-2003 20:02
From: someone
Originally posted by Tiger Crossing
While you're at it, toss in support for the P5 Glove! :D


Hmm, I wonder if LL would be able to get some kind of incentive from the manufacturer of the glove in exchange for making it compatible with SL...

Think they'd be willing to invest a bit in SL/LL if it was made compatible? Heh, nice marketing opportunities here.
Mark Busch
DarkLife Developer
Join date: 8 Apr 2003
Posts: 442
11-11-2003 21:56
Using analog joystricks/pads would have to send the amount of pushing continiously to SL and the script would have to update the motor speed all those times... I don't think it will work well.
Garoad Kuroda
Prophet of Muppetry
Join date: 5 Sep 2003
Posts: 2,989
11-11-2003 22:34
I thought you had a good point there at first but now I'm not so sure....how do all the other online games that use joysticks work? I can't see any real difference from those... granted, our current script power might not work well with it, but this is asking for some kind of special interface that *does* allow LSL to do this.

Eh, right? Am I making sense?
Huns Valen
Don't PM me here.
Join date: 3 May 2003
Posts: 2,749
11-11-2003 23:07
From: someone
Originally posted by Mark Busch
Using analog joystricks/pads would have to send the amount of pushing continiously to SL and the script would have to update the motor speed all those times... I don't think it will work well.


Let's see...
Five axes times eight bytes each = 40 bytes...
A sixteen-button joystick (does that even exist?) could be supported by adding another two bytes... so a 42-byte struct could send back every last bit of data you could possibly expect from even the most outrageously complex joystick. There are likely to be a lot of zeros in there, unless you plan on activating every axis and mashing down every last button at the same time, so the data should compress well (if it's even worth compressing at all).

Poll the joystick five times a second, that's 210 bytes a second. Poll it ten times a second, that's 420 bytes a second. I would guess that five updates per second would be more than enough. So you add 210 bytes per second (assuming it is not compressed) to the upload, or 420 if you want ten a second. I don't think that's going to break the bank.

Also... I like ZHugh's idea. Every flight sim I've seen has allowed the user to choose betwen keyboard+mouse and joystick.
Garoad Kuroda
Prophet of Muppetry
Join date: 5 Sep 2003
Posts: 2,989
11-12-2003 06:34
I think (?) the problem he's referring to has to do with lag and ping times. You can get data from the joystick a million times a second but you can only get the electricity to travel down the wires so fast...but--

Your estimate of about 5 times for second would be about a 200 ping right? Not too unreasonable unless you're Eggy's neighbor. (heh Europe sim needed?)

Other much more ping dependent games can do it, I'd imagine it'd work here.

Edit: NM the first sentence, I imagined that. He's talking about script speed.. in fact, I don't think Mark's talking about lag at all.
Huns Valen
Don't PM me here.
Join date: 3 May 2003
Posts: 2,749
11-12-2003 09:11
In any case, it would not be subject to any more lag than keyboard controls.

I will think about writing an RFC for ZHugh's idea, unless he or someone else should want to do it.