Basic Virtual HOTAS

Official forum for open source FreePIE discussion and development.
Post Reply
Gwathdring
One Eyed Hopeful
Posts: 7
Joined: Thu Nov 06, 2014 2:00 am

Basic Virtual HOTAS

Post by Gwathdring »

Hello!

I was making a very basic script to turn my Thrustmaster X Hotas into a more expansive virtual device. I was wondering if anyone interested in such things could give me a few pointers and let me know if there are more efficient ways to do what I'm doing and/or if I'm missing some important details that will make functionality more robust. The script is attached but I can post it, too, if preferred.

It's my first script with FreePie (or Python for that matter) so I'm sure I'm doing something sub-optimally. So far it seems to work though!

All it does at the moment is give my 16 button HOTAS (if we call the 4-way hat 4 buttons) 5 modes (4 shift buttons and Neutral) on 12 buttons for a whopping 60 buttons. I'm currently getting into my groove with the Freespace 2 engine and it definitely doesn't need quite so many joystick buttons since I have a laptop on the desk in front of me and can reach out and tap the keyboard for an functions that don't require particularly fast reaction time, but I can always reduce the number of modes or comment certain buttons out of the the shift patterns so they're always in neutral.

In any case, there are a few things I would like to do moving forward that I'd like some help with, other than general advice and corrections on what I've got started.

1) I would like to set some buttons as multi-function. For example, I would like holding down the glide button to put me into send the Glide command (G) until released while tapping it once sends the Toggle Glide command (alt-G). In my case, since I'm using a virtual joystick, I'd rather assign the tap and the hold to separate vJoy buttons. I only need to do this with one or two buttons but I'm not sure how to do it.

2) I want to issue button commands with the joystick in one of the modes. There are two buttons on the base that as such are require you to operate the HOTAS one-handed. I wanted to use them as shift buttons so I can quickly switch the X and Y axes on the main Joystick between the following states:

Neutral: Pitch and Yaw (2 axes, no mapping needed)
Button 11: Forward, Backward, Left and Right thrust (4 buttons)
Button 12: Up, Down, Left and Right thrust (4 buttons)

I'm also considering using the same functionality to turn my Slider into a two or four buttons (partial pressed, and full on in both directions) in one of the shift modes. What's the best way to do convert the analog input into a button press like that?


3) Currently, while functional for gaming, the setup has some oddities. Joystick 1 = my HOTAS, Joystick 2 = vJoy[15]. In this example I'm pressing button 0 which I'll call "Fire" since it's the main trigger.

Hold fire: joy1 and joy2 both report the same press.
Release fire: Everything back to normal.

Shift, hold fire: joy1 shows both buttons, joy 2 shows a single correctly shifted button.
(Still holding shift) Release fire: Everything behaves properly.
(still holding shift) Toggle fire: Everything behaves properly.

Shift, hold fire.
Release shift while holding fire: Joy 1 correctly reads Fire, but Joy 2 reads both Fire and holds the (now incorrectly) shifted button.

Now if I release Fire, everything goes back to normal.
If instead I Shift while still holding fire, and then release fire while still holding shift ...

Joy 1 now reports only Shift, as it should. Joy 2, though, reports Fire even though it should report nothing.

I'm guessing I missed a fairly basic step in setting up my button mappings. Probably some sort of reset stage in the script cycle.

4) Finally, I ran into some trouble with the script not liking an integer when I mapped the Slider like so:

Code: Select all

    vJoy[v_i].slider[v_slide_i] = joystick[phys_i].sliders[slide_i]
or like so:

Code: Select all

vJoy[v_i].slider[v_slide_i] = filters.mapRange(filters.deadband(joystick[phys_i].sliders[0], 0), -1000, 1000, -vJoy[v_i].axisMax, vJoy[v_i].axisMax)
I couldn't figure out what syntax it wanted to map the slider on my HOTAS to the virtual slider. So I just mapped it onto a rotation axis, which should be just fine for gaming purposes but I'm curious how I should have mapped the sliders to avoid errors.


Thanks!
You do not have the required permissions to view the files attached to this post.
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: Basic Virtual HOTAS

Post by CyberVillain »

I guess you ment something like Ctrl+C but for the joystick?

A not so elegant way is

Code: Select all

if joystick[0].getDown(0) and joystick[0].getPressed(1):
	#command 1
	
if joystick[0].getDown(0) and joystick[2].getPressed(1):
	#command 2
A better way is to create commands, look at this code, he is doing voice commands, but there is a base class so you can easily implement a Button Command

https://github.com/NoxWings/FreePie-Scr ... keyboardpy
Gwathdring
One Eyed Hopeful
Posts: 7
Joined: Thu Nov 06, 2014 2:00 am

Re: Basic Virtual HOTAS

Post by Gwathdring »

Thanks! I'll give that a try. Hmm. For some reason the "Key Hold" command isn't working for me in the voice command example. Any idea what's going on there? It recognizes the command, but it doesn't seem to successfully hold down the key--I just get one letter. The repeat function works fine, but pressing and holding doesn't seem to register.
Gwathdring
One Eyed Hopeful
Posts: 7
Joined: Thu Nov 06, 2014 2:00 am

Re: Basic Virtual HOTAS

Post by Gwathdring »

Hmm. I'm having trouble adapting this code. It's easy to see how to adapt the actions, but I'm having trouble adapting the Command classes.

Also I'm still not sure how to deal with Axes as per my initial post.
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: Basic Virtual HOTAS

Post by CyberVillain »

YOu can start with the second example first? Its not as nice but easier to understand
Gwathdring
One Eyed Hopeful
Posts: 7
Joined: Thu Nov 06, 2014 2:00 am

Re: Basic Virtual HOTAS

Post by Gwathdring »

I'm not sure that answers my question. I already have something that maps the buttons onto the virtual joystick when I shift. If uses an "If [shift button is pressed], then [alternative mappings] else [neutral mappings]" sort of structure so I don't see how it is different from your example.

As I said, I have something that works for getting everything mapped to vJoy and contains all my shifts. Here's what I have currently:

Code: Select all

	map_axis_to_vjoy (0, 15)
	if joystick[0].getDown (8):
		map_shift_s1 (0, 15)
	elif joystick[0].getDown (9):
		map_shift_s2 (0, 15)
	elif joystick[0].getDown (10):
		map_shift_s3 (0, 15)
	elif joystick[0].getDown (11):
		map_shift_s4 (0, 15)
	else:
		map_buttons (0, 15)
		map_hats (0, 15)
With each map_***** function looking like this:

Code: Select all

def map_shift_s1 (p, v):         ##This is our basic "S" class shift pattern. Mode 1.
	map_button_to_vjoy (p, 0, v, 8)
	map_button_to_vjoy (p, 1, v, 9)
	map_button_to_vjoy (p, 2, v, 10)
	map_button_to_vjoy (p, 3, v, 11)
	map_button_to_vjoy (p, 4, v, 12)
	map_button_to_vjoy (p, 5, v, 13)
	map_button_to_vjoy (p, 6, v, 14)
	map_button_to_vjoy (p, 7, v, 15)
	map_hat_to_vjoy_button (p, 0, 0, v, 16)     ##Hat U, R, D, L
	map_hat_to_vjoy_button (p, 0, 9000, v, 17)
	map_hat_to_vjoy_button (p, 0, 18000, v, 18)
	map_hat_to_vjoy_button (p, 0, 27000, v, 19)
What advantage does individual "AND" statements have over this? Would the "AND" structure fix the weirdness when releasing the shift button? Logically it doesn't seem like it should be different.

I guess I'll just try it and see. In any case, I have the basic version down then whether it's with "AND" statements or "If" statements.

But that's a solved problem, then. You say the command structure would be better but I'm still not sure how to best handle translate the the two Command classes in the v2k command structure. It's quite clear how to turn KeyAction into a ButtonAction and KeyPress into ButtonPress and so on and so forth. I've got that part down. I was able to get voice commands to press virtual joystick buttons (though holding still doesn't work). What I'm not sure of is how I should structure physical joystick inputs so as to match the "VoiceCommand" classes in v2k.


P.S. Also the "hold key" doesn't even work in the original v2k pulled straight from git. Always just gives 1 key. Is this something on my end or is something wrong with the code?
NoxWings
One Eyed Hopeful
Posts: 44
Joined: Thu May 15, 2014 8:04 am

Re: Basic Virtual HOTAS

Post by NoxWings »

If you want to use the "KeyHold" "KeyPress" you will have to implement them, they are not built-in.

If you have a little bit python understanding you could easily use/mod my implementation:
https://github.com/NoxWings/FreePie-Scr ... eyboard.py
Gwathdring
One Eyed Hopeful
Posts: 7
Joined: Thu Nov 06, 2014 2:00 am

Re: Basic Virtual HOTAS

Post by Gwathdring »

That's the implementation I'm trying to modify; it was linked in the second post by CyberVillain.

I'm having trouble getting it to do what I want--in your VoicetoKeyboard script, the KeyPress function doesn't work when I input a duration for a key to be held. It just presses the key once. KeyRepeat works and KeyPress works without duration but it doesn't seem to pay attention to duration input.
NoxWings
One Eyed Hopeful
Posts: 44
Joined: Thu May 15, 2014 8:04 am

Re: Basic Virtual HOTAS

Post by NoxWings »

Gwathdring wrote:That's the implementation I'm trying to modify; it was linked in the second post by CyberVillain.

I'm having trouble getting it to do what I want--in your VoicetoKeyboard script, the KeyPress function doesn't work when I input a duration for a key to be held. It just presses the key once. KeyRepeat works and KeyPress works without duration but it doesn't seem to pay attention to duration input.
Are you testing it in-game? For some reason keyboard plugin does not work as expected outside of a game.
I ran into the exact same problem while I was testing my first FreePIE script in notepad.
Gwathdring
One Eyed Hopeful
Posts: 7
Joined: Thu Nov 06, 2014 2:00 am

Re: Basic Virtual HOTAS

Post by Gwathdring »

I was testing it using the raw-input monitor on my virtual joystick, but not in game. I'll try that, but it seems like it shouldn't make a difference ... that doesn't make very much sense.
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: Basic Virtual HOTAS

Post by CyberVillain »

You are taking about different things (I think) Nox talks about emulating keyboard and Gwathdring about emulating joystick.
Correct? I do actually not know how vJoy emulates buttons being pressed over a long time

try

Code: Select all

if starting:
   vJoy[0].setButton(0, True)
Look under Game controller ("Set up usb game constrollers" under start menu), is the button being pressed?
Gwathdring
One Eyed Hopeful
Posts: 7
Joined: Thu Nov 06, 2014 2:00 am

Re: Basic Virtual HOTAS

Post by Gwathdring »

Yep, that does it just fine.

Further, I was talking about both! I tried VoicetoKeyboard out-of-the-box with voice commands going to keyboard inputs as well as changing to voice commands for joystick inputs. The result was the same--the KeyHold command didn't work. I would read out voice commands with Notepad open and it would type the single and repeated keys but it wouldn't hold a key.

But your simpler command works fine as did my direct 1:1 mapping from my original post.
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: Basic Virtual HOTAS

Post by CyberVillain »

It does not work with notepad, its same with Glovepie, try with a game it holding will work
Post Reply

Return to “FreePIE”