Comments (49)
I think directional rumble should also be possible...
from xpadneo.
Documentation: FF report (ID 03
)
<--- MSB/MSb --- LSB/LSb ---
LLLL LLLL
SSSS SSSS
DDDD DDDD
4444 4444
3333 3333
2222 2222
1111 1111
XXXX EEEE
E - Enable Actuators
0x01
: Rumble Right
0x02
: Rumble Left
0x04
: Impulse Trigger Right
0x08
: Impulse Trigger Left
X - Padding
1 - Magnitude
Impulse Trigger Left
2 - Magnitude
Impulse Trigger Right
3 - Magnitude
Rumble Left
4 - Magnitude
Rumble Right
D - Duration
In seconds*10^-2 = 0,01s
S - Start Delay
In seconds*10^-2 = 0,01s
L - Loop Count
How often should we repeat the effect
from xpadneo.
I think directional rumble should also be possible...
Not over BT i fear - since the HID output report 03
is exhausted now (previously i thought the other bits are reserved)
from xpadneo.
I don't know the interfaces, but since we have left and right rumble, directional rumble is possible. In wine joy.cpl I see that you can set a direction for rumble effects.
from xpadneo.
ah i see - directional in the sense of right/left! yes, thats for sure possible! :)
what i thought you mean is if the force pulls/pushes into a specific direction
from xpadneo.
struct ff_effect {
__u16 type;
__s16 id;
__u16 direction;
struct ff_trigger trigger;
struct ff_replay replay;
union {
struct ff_constant_effect constant;
struct ff_ramp_effect ramp;
struct ff_periodic_effect periodic;
struct ff_condition_effect condition[2]; /* One for each axis */
struct ff_rumble_effect rumble;
} u;
};
struct ff_rumble_effect {
__u16 strong_magnitude;
__u16 weak_magnitude;
};
Unfortunately I fear there is no impulse trigger support at the moment (at the linux kernel). Furthermore, the directional effect does not really make sense at the Xbox One Wireless Controller since both sides (left/right) do only offer one of both effects (strong rumble/weak rumble). They rumble hardware is not equal.
But maybe I overlooked something, I will dig a bit deeper.
from xpadneo.
I don't think that impulse trigger should be a rumble effect but instead a force feedback effect... Does Linux support force feedback (I mean, really applying counter force instead of playing just rumble effects) - then that would be the way to go.
BTW: This feature isn't even supported by the Windows driver as far as some research shows. And the Steam community is full of posts about alternative drivers which support more Xbox controller features than the one MS provides in Windows.
https://www.youtube.com/watch?v=G4PHupKm2OQ
from xpadneo.
I think directional feedback should go as far as giving me feedback in a shooter if I'm hit from left or right. This is probably up to the game, as long as the interface is provided.
Impulse triggers would be interesting for features like the shock when pulling the trigger to fire your weapon, or for driving simulations by sending feedback from the wheels or the motor. Also see previous youtube link.
from xpadneo.
I don't think that impulse trigger should be a rumble effect but instead a force feedback effect... Does Linux support force feedback (I mean, really applying counter force instead of playing just rumble effects) - then that would be the way to go.
Well, as far as I know rumble is just a special kind of force feedback, at least in the sense the kernel handles it.
The kernel does in fact support a bunch of FF effects, those are:
FF_CONSTANT can render constant force effects
FF_PERIODIC can render periodic effects with the following waveforms:
FF_SQUARE square waveform
FF_TRIANGLE triangle waveform
FF_SINE sine waveform
FF_SAW_UP sawtooth up waveform
FF_SAW_DOWN sawtooth down waveform
FF_CUSTOM custom waveform
FF_RAMP can render ramp effects
FF_SPRING can simulate the presence of a spring
FF_FRICTION can simulate friction
FF_DAMPER can simulate damper effects
FF_RUMBLE rumble effects
FF_INERTIA can simulate inertia
FF_GAIN gain is adjustable
FF_AUTOCENTER autocenter is adjustable
(take a look here)
But none of those does really fit, right? To be honest, it is just a rumbling motor, so something like FF_RUMBLE_TRIGGER would be best, but it does not exist (at the moment).
Our best bet seems to be FF_CONSTANT, since this seems to be the only one which is at least implemented in some drivers (but mostly wheels).
Is this what you meant? Something like the counterforce while driving?
It is not really a counterforce but yeah, the idea is somehow the same and it could be fun at car games I think ^^
Another solution would be to let the triggers rumble whenever the "normal" rumble occurs. What would you, as a gamer, prefer?
from xpadneo.
I think directional feedback should go as far as giving me feedback in a shooter if I'm hit from left or right. This is probably up to the game, as long as the interface is provided.
Ah, mhm, for a short period it is okay I think. But a shot from the left feels a bit different than one from the right then ;D
We would need two rumble motors (a weak one and a strong one) on both sides to fit the structure as it is in the kernel.
Where is why:
The FF_RUMBLE
interface does offer you to set those properties separately. You can say you want a bit of a strong rumble and much of the weak at the same time at the left hand, and nothing at the right.
In practice this isn't possible - since most gamepads only have two rumble motors, one is the weak one, the other one is the strong one - and they are placed like: weak -> right handle, strong -> left handle (or vice versa).
Therefore, we totally ignore the left/right directional property until now.
Imagine the game requests a rumbling effect on the left using the motor (weak/strong) which is on the right - how should we do that? The only thing we could do then is to approximate the effect magnitude using the wrong motor (if a bit of strong rumbling is requested on the side where the weak motor is, then we could rumble a bit harder using the weak one). But yes, it is just an approximation then.
Again @kakra: What do you think, should we prefer to offer directional effects or to be more precise?
from xpadneo.
The Steam controller is pretty capable of emulating most of the effects. It doesn't have rumbling motors but small magentic accelerators that work like in a sound speaker, and for different directions. This is why the effect is very subtle and makes sounds. But if you flip the finger across the touch pad, it feels like a track ball is rotating with inertia, and when you stop it, you can feel that stopping shock, too. It has friction effects when you program a pad with virtual buttons. The triggers have a non-programmable hardware trigger point near the end (with some higher, clicking force). The Steam input driver can try to emulate many effects, but it's far from rumble.
For the Xbox controller I could also think of FF_SPRING could be a usable effect. But without ever experiencing it, I cannot really help here. Do you have a test program which could play the trigger effects built into the controller?
from xpadneo.
Ah, here I see what you mean: https://zh.ifixit.com/Guide/Xbox+One+Wireless+Controller+Trigger+Rumble+Motor+Replacement/36558
So, essentially the problem is that we have only two axis in the interface to apply FF effects to?
from xpadneo.
BTW: From the pictures, it looks to me like the strong motors are left and right in the grips, and the weak motors in the triggers. Also, when I opened my F710, it had two identical motors on each side. Can you just turn the motors on and off, or is it possible to apply a value for rotation speed?
from xpadneo.
I just found that there's ffmvforce
and ffcfstress
additionally to fftest
. While the former does nothing, the latter claims the controller has no support.
from xpadneo.
I just found that there ffmvtest and ffcfstress additionally to fftest. While the former does nothing, the latter claims the controller has no support.
I didn't knew about the others but I always used/use fftest
here, and it is still working for me:
fftest /dev/input/event14
Force feedback test program.
HOLD FIRMLY YOUR WHEEL OR JOYSTICK TO PREVENT DAMAGES
Device /dev/input/event14 opened
Features:
* Absolute axes: X, Y, Z, RX, RY, RZ, Hat 0 X, Hat 0 Y,
[3F 00 03 00 00 00 00 00 ]
* Relative axes:
[00 00 ]
* Force feedback effects types: Periodic, Rumble, Gain,
Force feedback periodic effects: Square, Triangle, Sine,
[00 00 00 00 00 00 00 00 00 00 03 07 01 00 00 00 ]
* Number of simultaneous effects: 16
Setting master gain to 75% ... OK
Uploading effect #0 (Periodic sinusoidal) ... OK (id 0)
Uploading effect #1 (Constant) ... Error: Invalid argument
Uploading effect #2 (Spring) ... Error: Invalid argument
Uploading effect #3 (Damper) ... Error: Invalid argument
Uploading effect #4 (Strong rumble, with heavy motor) ... OK (id 1)
Uploading effect #5 (Weak rumble, with light motor) ... OK (id 2)
Enter effect number, -1 to exit
From the pictures, it looks to me like the strong motors are left and right in the grips, and the weak motors in the triggers. Also, when I opened my F710, it had two identical motors on each side. Can you just turn the motors on and off, or is it possible to apply a value for rotation speed?
For every kind of effect, you can set a direction:
- 0 deg -> 0x0000 (down)
- 90 deg -> 0x4000 (left)
- 180 deg -> 0x8000 (up)
- 270 deg -> 0xC000 (right)
Furthermore, there are effect-specific properties. For the FF_RUMBLE effect, you can also set:
- strong_magnitude (left grip), 0 to 0xFFFF
- weak_magnitude (right grip), 0 to 0xFFFF
That's the software part. The hardware looks like the following:
We have three kinds of motors:
- a strong one, which is in the left grip
- a not-so-strong one, which is in the right grip
- two very small ones at the triggers
You can see the difference between the grip-motors (the weights) here.
We can set a "rotational speed" for all four motors independently.
Given that information, how would you handle an effect request, which wants:
- direction: right
- strong_magnitude: 0x80FF
- weak_magnitude: 0x0000
The strong motor is on the left, but the direction requests an effect on the right side...^^
As I said above, the only way to offer both - directional effects and the normal RUMBLE thing, is appoximation in my eyes. I think that's most probably what most drivers do (unchecked).
For the Xbox controller I could also think of FF_SPRING could be a usable effect. But without ever experiencing it, I cannot really help here. Do you have a test program which could play the trigger effects built into the controller?
You mean experiencing the Impulse Trigger thingy? I can simply implement first support and we can decide on how exactly the interface should look like later - then you can test it too.
from xpadneo.
It would make sense to have this test program when it could somehow access the trigger motors. It would be nice if it supported raw access to the functions so we could experiment with it. Is it possible to bypass the hid driver and access hidraw for this?
I could think of this solution:
Depending on the direction (left or right), not just play the strong or weak motor, but also the left or right trigger motor. If direction is forward, play both trigger motors. If backward, play no trigger motor but just the weak or strong motor. What do you think?
from xpadneo.
BTW: Interesting... If I put the controller on the table and push down on the left grip only with a finger tip, playing the strong effect creates a strong pull to the right. Pushing down on the other side, it just wobbles. Can we exploit that somehow? ;-)
from xpadneo.
It would make sense to have this test program when it could somehow access the trigger motors. It would be nice if it supported raw access to the functions so we could experiment with it. Is it possible to bypass the hid driver and access hidraw for this?
I will give it a try and report back.
Depending on the direction (left or right), not just play the strong or weak motor, but also the left or right trigger motor. If direction is forward, play both trigger motors. If backward, play no trigger motor but just the weak or strong motor. What do you think?
That's indeed a very clever but still a bit dirty solution.
The only really clean one is to change even more kernel code, I fear. I think I will write Vojtech Pavlik (the author of the input subsystem) an eMail - he probably knows it the best.
from xpadneo.
Let's be dirty then... ;-)
Even if kernel interfaces changed, it will take time for games to adapt. So this dirty solution would be some sort of "legacy" mode. And we can add a modern mode later and expose that as a configurable module parameter so you can choose which interface suits your needs.
from xpadneo.
It would make sense to have this test program when it could somehow access the trigger motors. It would be nice if it supported raw access to the functions so we could experiment with it. Is it possible to bypass the hid driver and access hidraw for this?
I will give it a try and report back.
If you provide the basic framework, I could add the rest of the code to it.
from xpadneo.
Okay, as a temporary solution 😄 as long as there is no better kernel-support.
To sum it up: We will use the directional information for the trigger-motors for now.
Therefore the strength of the rumble at the right/left trigger will be influenced by two factors:
- direction of the effect
- right -> right trigger
- forward -> both triggers
- left -> left trigger
- backwards -> none
- magnitude of the strong motor
- the magnitude of the effects played at the triggers are proportional to the magnitude of the effect played on the strong motor
Agreed?
from xpadneo.
Sounds fine, I was already thinking about it.
As far as I can see, we can play the strong and weak motor independent of each other or at the same time, with a magnitude of 0 to 100% each. We should stick with a 1:1 mapping here to not change how games expect it to work.
Now we emulate a direction. The further up the direction points, the stronger the magnitude. Point north should play both trigger motors at 100%. I think you'll need sine/cosine tables for it. But we can make it linear first and see if that easy solution works well enough.
What do we do with the south direction? Should we map the complete Y axis of the circle to 0 to 100% (from bottom up), or just the upper half of the circle, and let the lower half just not play the triggers at all? I think the latter implementation could make more sense since the triggers are in the front only. The lower half could instead bias the grip motors instead. But we should not do this in the first implementation as it could violate games expectations.
from xpadneo.
As far as I can see, we can play the strong and weak motor independent of each other or at the same time, with a magnitude of 0 to 100% each. We should stick with a 1:1 mapping here to not change how games expect it to work.
That's correct! What do you mean by 1:1 mapping?
Now we emulate a direction. The further up the direction points, the stronger the magnitude. Point north should play both motors at 100%. I think you'll need sine/cosine tables for it. But we can make it linear first and see if that easy solution works well enough.
Maybe not at 100% but at most as strong as e.g. the strong motor is playing? What do you think? Would be a bit strange it the Triggers are rumbling more than the Gampad itself.
What do we do with the south direction? Should we map the complete Y axis of the circle to 0 to 100% (from bottom up), or just the upper half of the circle, and let the lower half just not play the triggers at all? I think the latter implementation could make more sense since the triggers are in the front only.
I agree, I would also go fot the latter one.
from xpadneo.
This latter solution has the advantage that you can play rumble without triggers by just pointing backward. Otherwise we would always have triggers rumble with no chance to prevent that.
1:1 means keep it how it works currently, not influenced by direction.
from xpadneo.
0 = 0x0000, 2 = 0x2222 etc
0 to 4 and C to F map both trigger motors to off.
4 to 6 maps trigger left to 0-100%, right to 0%
6 to 8 maps trigger left to 100%, right to 0-100%
8 to A maps trigger left to 100-0%, right to 100%
A to C maps trigger left to 0%, right to 100-0%
Playing weak or strong only chooses the grip motors, no effect on trigger magnitude.
This way it should be possible to play every combination of magnitude with every motor, right?
It should even be possible to rumble the triggers only by sending a magnitude of 0 to the grip motors.
from xpadneo.
1:1 means keep it how it works currently, not influenced by direction.
I see, yes for sure - the direction will only influence the "new" trigger buttons. Everything else stays as normal.
Playing weak or strong only chooses the grip motors, no effect on trigger magnitude.
Imagine that a game invokes an super-duper light effect on the left. This way (which you mentioned) the gamepad would play a very strong effect at the left trigger, which is way stronger than the main-rumbling which was requested. I therefore think that the grip-magnitude (which is the only we have) should influence the triggers too.
So my suggestion would be:
0 to 4 and C to F map both trigger motors to off.
4 to C maps trigger left to 100-0%, right to 0-100%, with 50%/50% at 8
from xpadneo.
I hope I find a game to test that... ;-)
from xpadneo.
Playing weak or strong only chooses the grip motors, no effect on trigger magnitude.
Imagine that a game invokes an super-duper light effect on the left. This way (which you mentioned) the gamepad would play a very strong effect at the left trigger, which is way more strong than the main-rumbling which was requested. I therefore think that the grip-magnitude (which is the only we have) should influence the triggers too.
Maybe we could add a trigger_bias
module parameter which sets how much the trigger motors are influenced by the grip motor magnitude. But if weak and strong play at the same time: Which magnitude will you choose?
from xpadneo.
Maybe the choosen magnitude should not be a multiple of all magnitudes and a bias how I first imagined but simply a max of (weak,strong,directional). A module parameter then instead chooses if this max() value is used or if only directional is used.
from xpadneo.
Maybe we could add a trigger_bias module parameter which sets how much the trigger motors are influences by the grip motor magnitude.
For sure, that's not a problem.
But if weak and strong play at the same time: Which magnitude will you choose?
Maybe something like max{strong,weak}
, I think that's something we will have to evaluate then.
from xpadneo.
Ah yes, max(weak,strong)*directional makes more sense ;-)
from xpadneo.
Or min(directional,max(weak,strong))...
from xpadneo.
Ah yes, max(weak,strong)*directional makes more sense ;-)
Perfect! Let's do it like that - it's easy to change afterwards if it does not work as expected ;) As always: Thank you very much and good night ;D
from xpadneo.
Looking forward, I'll now research which Linux games could support that. At least wine joy.cpl has a directional interface for rumble. Maybe you could look at the source and see if and how it translates that to Linux... Then, I could try games in Wine. I'm not sure if one of the pseudo-native Linux games would support directional rumble.
from xpadneo.
Looks like DIRT, GRID and Eurotruck Simulator 2 have support for directional FF. Tho, it may be used for centering the steering wheel. At least, I believe I have all three in my Steam library as native Linux games.
from xpadneo.
pushed a first version which enables the other two motors, will do the math tomorrow (later). At least you can experience it with fftest
now! Night! ;)
Btw: The magnitude for the triggers are downscaled to a fourth(!)
from xpadneo.
Aw well, night time for me, too.
from xpadneo.
in addition to the commit above i've added a very very basic test tool.
next steps:
- replace the LUT by a simple and (more) continuous calculation
- transfer the magic
4
in(u8)(((max / 4) * proportion_left_trigger) / 1000);
to a parameter (gain) - (extend the test program)
- clean up
from xpadneo.
@kakra: this is what you are talking about, right?
edit: ups, alpha should be alpha = (180 / 0x8000) * value - 90
edit2: damn it, my math teacher would kill me... mixed up left and right too xD
from xpadneo.
Yes, tho I don't think we need curve functions. We can simply make it linear per each 45 degrees - at least for the start.
Then a series of if clauses just does the math:
if x in 0x0000...0x4444 or x in 0xCCCC...0xFFFF then directional = { left: 0, right: 0 }
if x in 0x4444...0x6666 then directional = { left: (x-0x4444)/0x2222, right: 0 }
if x in 0x6666...0x8888 then directional = { left: 1, right: (0x8888-x)/0x2222 }
You get the idea... Pseudo code, "..." meaning non-inclusive (as in Ruby). The 0xFFFF check has to do an inclusive check. Or better, it checks against 0x10000, as actually the 0x1111 are endless fractionals and in that definition 0xFFFF does not exist. This is the fraction of 1/9, which makes 0.11111..., 0.22222... and so on but 0.999999... does not exist: It's equal to 1.
Does it make sense? The circle has four or eight slices which is perfectly easy to do with a hexadecimal radial scale. How did I think we need to use 0x2222 etc? Well, whatever, the idea is the same.
PS: I should have drawn the complete circle with slice 0-F instead of only the upper half 4-C, then I would have seen my error. Go with 0x2000, 0x4000 instead. ;-)
from xpadneo.
ef8d113
Used an cosine LUT, think this is the easiest and best looking way - but you're right, feels better now
from xpadneo.
I've added the parameter trigger_rumble_damping
(0 to 8, non-linear), so in theory it is ready 😃
Will close this issue within 24 hours if everything seems to be fine.
from xpadneo.
Let me test this, hopefully today or tomorrow.
from xpadneo.
I've added an test program yesterday, at least here it works
./directional_rumble_rest <eventnumber> [<magnitude, 0 to 65535>]
Im curious how it feels ingame :game:
from xpadneo.
@kakra have you found any native linux game that supports directional rumble? :)
from xpadneo.
Not yet, or at least I didn't sense it doing so. But I found that sometimes, FF effects play, and sometimes they don't. Usually, that's pretty consistent throughout the gameplay: When it's missing from the start, FF usually never plays. When it works, it sometimes misses playing FF effects when there should be effects. I'm yet to figure this out better. It's somehow similar to how my modified test program plays only the first round of effects...
from xpadneo.
I didn't yet came across a game that uses directional rumble. The rumble effects sometimes missing didn't occur in a while. It's consistently working in games currently.
from xpadneo.
Thank you for getting back 👍
from xpadneo.
Closing - works
from xpadneo.
Related Issues (20)
- Xbox one S controller has R input on it's own HOT 15
- Gulikit KingKong2 Pro Controller does not stop rumbling when connected HOT 1
- guid button not working proerly HOT 8
- xpadneo module not loading correctly when connecting Bluetooth Controller HOT 5
- Xbox Series X|S controller recognized as 360 controller and no inputs detected in games HOT 12
- Prevent axis fixup and get xbox elite 2 layout in steam HOT 2
- xpadneo 0.9.5 not loading on Ubuntu 22.04 Linux kernel 6.5.0 HOT 7
- Double Input / Ghost Input HOT 9
- Controller rumble has stopped working HOT 21
- Vibration not work on Gamesir T4 Pro HOT 7
- When xbox controller is not actively connected to bluetooth, bluetooth will suddenly stop working for other bluetooth devices. HOT 1
- Did not find any bluetooth devices fedora 39. HOT 4
- Packaging issue HOT 4
- Gulikit kk3 max recognized as 360 and rumble issues HOT 1
- Series controller not found at all HOT 7
- How To Update Controller Firmware through Xbox Accessories and VirtualBox HOT 1
- Steam and Wine not seeing any sort of input on the controls HOT 2
- Triggers getting stuck after releasing them HOT 9
- Xbox Controller still shown as connected after disconnecting HOT 4
- Controllers do not register as joysticks after reboot HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from xpadneo.