input-remapper icon indicating copy to clipboard operation
input-remapper copied to clipboard

Feature: analog axis with trigger threshold

Open kopach opened this issue 1 year ago • 6 comments

Hi. I would like to use my racing pedals as rudder in flight simulator. So, I need to combine accelerator & clutch pedals into 1 axis.

I'ts currently possible to output 2 axis input into a single output axis (and even revert direction per input axis) with config like this

2024-02-06_19-54 2024-02-06_19-54_1

However, the result is not as expected. When 1 pedal - I can go from 0 to 100%. When pressing 2 pedals - those get interfered 2024-02-06 19 55 45

Desired

What I would like to have is when pedals are not pressed - output axis is in the middle. With 1 pedal - we should be able to change only half of the output axis scale

2024-02-07 23 38 39

Ref On Windows it's possible to accomplish combining vJoy and UCR. Here is demonstration of concept https://forums.flightsimulator.com/t/sim-racing-pedals-as-rudder-without-additional-software-l-r-rudder-axes-how-do-they-work/400075

kopach avatar Feb 06 '24 19:02 kopach

Found some reference on how to do this in Python with FreePIE (Windows only), maybe could be helpful here https://gist.github.com/gyrovague/a2a4ef1bc5f84936ebcfb7f72ca67b08

kopach avatar Feb 07 '24 23:02 kopach

I think an Analog threshold is already possible just not with the UI You can edit the the preset .json file (~/.config/input-remapper-2/presets/<your device>/<preset name>.json) it should contain the two analog mappings:

[
    {
        "input_combination": [
            {
                "type": 3,
                "code": 2,
                "origin_hash": "eb7dd9f8f5366ecb356deaff3f42b9f8"
            }
        ],
        "target_uinput": "gamepad",
        "output_type": 3,
        "output_code": 0,
        "mapping_type": "analog",
        "deadzone": 0.0
    },
    {
        "input_combination": [
            {
                "type": 3,
                "code": 5,
                "origin_hash": "eb7dd9f8f5366ecb356deaff3f42b9f8"
            }
        ],
        "target_uinput": "gamepad",
        "output_type": 3,
        "output_code": 0,
        "mapping_type": "analog",
        "deadzone": 0.0,
        "gain": -1.0
    }
]

you can change the input section of each by just copying the already existing input and adding a analog_threshold like so:

[
    {
        "input_combination": [
            {
                "type": 3,
                "code": 2,
                "origin_hash": "eb7dd9f8f5366ecb356deaff3f42b9f8"
            },
            {
                "type": 3,
                "code": 2,
                "origin_hash": "eb7dd9f8f5366ecb356deaff3f42b9f8",
                "analog_threshold": 1
            }
        ],
        "target_uinput": "gamepad",
        "output_type": 3,
        "output_code": 0,
        "mapping_type": "analog",
        "deadzone": 0.0
    },
    {
        "input_combination": [
            {
                "type": 3,
                "code": 5,
                "origin_hash": "eb7dd9f8f5366ecb356deaff3f42b9f8"
            },
            {
                "type": 3,
                "code": 5,
                "origin_hash": "eb7dd9f8f5366ecb356deaff3f42b9f8",
                "analog_threshold": 1
            }
        ],
        "target_uinput": "gamepad",
        "output_type": 3,
        "output_code": 0,
        "mapping_type": "analog",
        "deadzone": 0.0,
        "gain": -1.0
    }
]

This is basically the same as moving two axes at the same time and using one of them as an analog input and the other as a key input. InputRemapper will now only trigger the mapping once the "key" is pressed and the axis is moving. It just so happens that the "key" input and the axis input are actually the same axis. The UI does not support this because it is not possible to record the same axis twice.

Note: InputRemapper always assumes axis to be symmetrical like joystic axis (from -100% - +100%) so the threshold can be positive or negative and will always trigger outside of the threshold. Positive threshold will trigger above the threshold and negative will trigger below the threshold.

Edit: Json is picky about having no trailing commas

jonasBoss avatar Feb 08 '24 14:02 jonasBoss

Also I am not sure if this really solves your problem. This will just start each mapping once you have pushed the pedal beyond 50% (beyond the 0 point if the pedal were a symmetrical axis).

A better solution would require two new features:

  1. Axis Offset. the zero position of the input pedal needs to be mapped to the 50% position of the output axis.
  2. Proper merging of two axes. I think currently only the axis which has the most up to date information is considered (if one axis is moving and the other is stationary the moving one is used). Maybe as a first implementation we can just add up the values of two axes and cutoff the result to the maximum allowed value.

In general it is possible to not only merge Absolute axis but also Relative axis or a Relative with a Absolute axis, we would need to find a solution that can support all those possibilities.

jonasBoss avatar Feb 08 '24 14:02 jonasBoss

Hi @jonasBoss, thanks for your support here. Yes, Axis Offset could be a good enough option (at least initially) as with proper rudder pedals it's usually should not be possible to press both pedals simultaneously anyway. Can you help me to understand where to start with this? I'm not much familiar with Python, but can try.

As for second (extra) solution, here is how it's implemented in UCR (GIF in description is from there) https://github.com/Snoothy/UCR/blob/b8884f634732f6920a0e4fef763c3a30c5ed5a27/UCR.Plugins/Remapper/AxisMerger.cs#L69

They do exactly as you've described: add up values, divide by 2 and later cutoff by "dead zone".

valueOutput = (short) ((valueHigh + valueLow) / 2);

and then

valueOutput = _deadZoneHelper.ApplyRangeDeadZone(valueOutput);

Another solution I've referenced above uses a bit different approach but looks legit as well

max = vJoy[vjidx].axisMax
min = -max

and then

get_right_pedal()-get_left_pedal())*max

What do you think?

kopach avatar Feb 08 '24 17:02 kopach

I think an Analog threshold is already possible just not with the UI You can edit the the preset .json file (~/.config/input-remapper-2/presets/<your device>/<preset name>.json) it should contain the two analog mappings:

@jonasBoss, thanks for this. It's somewhat workable temporary workaround. I only had to change "analog_threshold" to -1 instead of 1 otherwise it would "start" from from beginning and "finish" at 50%. What I want is that each pedal starts at "50%". Now I'll physically restrict my pedals to half release (be 50% pressed while in rest) and that will do the trick. Here is mapping for the reference

[
  {
    "input_combination": [
      {
        "type": 3,
        "code": 1,
        "origin_hash": "164adbd95baa725a490cd06825090af5"
      },
      {
        "type": 3,
        "code": 1,
        "origin_hash": "164adbd95baa725a490cd06825090af5",
        "analog_threshold": -1.0
      }
    ],
    "target_uinput": "gamepad",
    "output_type": 3,
    "output_code": 0,
    "name": "right pedal",
    "mapping_type": "analog",
    "deadzone": 0.0,
    "gain": -1.0
  },
  {
    "input_combination": [
      {
        "type": 3,
        "code": 5,
        "origin_hash": "164adbd95baa725a490cd06825090af5"
      },
      {
        "type": 3,
        "code": 5,
        "origin_hash": "164adbd95baa725a490cd06825090af5",
        "analog_threshold": -1.0
      }
    ],
    "target_uinput": "gamepad",
    "output_type": 3,
    "output_code": 0,
    "name": "left pedal",
    "mapping_type": "analog",
    "deadzone": 0.0,
    "gain": 1.0
  }
]

kopach avatar Feb 08 '24 21:02 kopach

I've installed Input Remapper on my Steam Deck and with config provided, I could finally play flight simulators (like Condor 2 or Acro FS) using sim racing pedals and joystick. I'ts quite playable this way. Can't wait for proper axis merger solution though.

kopach avatar Feb 13 '24 08:02 kopach