"Game Controller" does not call back on all axis

Questions about deployment and use of Air Manager Instruments

Moderators: russ, Ralph

Message
Author
Tetrachromat
Posts: 236
Joined: Sun Feb 14, 2021 6:55 pm

Re: "Game Controller" does not call back on all axis

#11 Post by Tetrachromat »

Having used the 4.1 BETA today for testing the character displays I have noticed an issue on the yoke that is probably related to your message:
Corjan wrote: Wed Jun 30, 2021 9:30 am Hi,


Just tested it, and found the issue (I think).
For some reason, the library I use ignores the first two axis and wont report them changing.

I have no idea why, it feels like I don't understand how it should work :)

Anyways, I changed it to not ignore them, and now it works.


Will be in AM 4.1 BETA when it releases,

Corjan
Ailerons and elevator, which I have assigned to the two primary axis (X an Y) are very slow to move. When I move the yoke forward and back to center the elevator is still moving down while the yoke is already back at center position and it is moving very slowly.

Throttle, Mixture and Flaps, which I have assigned to other axis behave normally. They are moving to the given setting in the same way you can see in AM 4.0.2.


UPDATE:
Actions on axis 0 and 1 are causing Air Manager to be completly unresponsive.WhenI try to close the AM application, In get an error message indicating that OpenJDK Platform binary is not reponding.

UPDATE 2:
From the logs I can see that there are more than 11´000 callbacks per second for axis 6:. I think this massive callbacs cause the stalling of Air Manager.

Code: Select all

2021-07-04 20:51:43 INFO  SiRunner - MSFS Controller - Flight Yoke System: called with type = 0, index = 6, input = 0.0
Axis 6 is the POV multiway switch, not a true axis. It produces the values -1.0 (pressed left), 0 (released), +1.0 (pressed right)
the calbacks should only occure when the value changes between those 3 values.

Paul
Last edited by Tetrachromat on Sun Jul 04, 2021 7:16 pm, edited 2 times in total.

Tetrachromat
Posts: 236
Joined: Sun Feb 14, 2021 6:55 pm

Re: "Game Controller" does not call back on all axis

#12 Post by Tetrachromat »

I just rechecked my Rudder Pedal action with the AM 4.1 BETA. It looks like that the axis associations have changed

With that LUA code

Code: Select all

-- MSFS Game Controller
-- Saitek Pro Flight Rudder Pedals

local controller = "Flight Rudder Pedals"
local gc_id = nil

local axis = {} 
axis[0] = { event = "AXIS_LEFT_BRAKE_SET",   range =  16383 }
axis[1] = { event = "AXIS_RIGHT_BRAKE_SET",  range =  16383 }
axis[2] = { event = "AXIS_RUDDER_SET",       range =  16383 }

function callback(type, index, input)
  log("called with type = " .. type .. ", index = " .. index .. ", input = " .. tostring(input))
  if type == 0 and index < 3 then
    event = axis[index].event
    if event then
      output = math.floor(axis[index].range * var_cap(input, -1.0, 1.0))
      fs2020_event( event, output )
      log("sent event " .. event .. " with value " .. output)
    end
  elseif type == 0 and index >= 3 then
    if input > 0 then
      event = axis[index].inc
      if event then 
        fs2020_event( event )
        log("sent event " .. event )
      end
    elseif input < 0 then
      event = axis[index].dec
      if event then 
        fs2020_event( event ) 
        log("sent event " .. event )
      end
    end
  elseif type == 1 and index < 0 then
    if input then
      event = bttn[index].on_press
      if event then 
        fs2020_event( event )
        log("sent event " .. event )
      end
    else 
      event = bttn[index].on_release
      if event then 
        fs2020_event( event )
        log("sent event " .. event )
      end
    end 
  end
end

gc_id = game_controller_add(controller, callback)
if gc_id then
  log("Game Controller added.")
end
-- END - 
I get the following log output on start up:

Code: Select all

2021-07-04 20:14:07 INFO  SiRunner - MSFS Controller - Flight Rudder Pedals: Game Controller added.
2021-07-04 20:14:07 INFO  SiRunner - MSFS Controller - Flight Rudder Pedals: called with type = 0, index = 0, input = 0.0
2021-07-04 20:14:07 INFO  SiRunner - MSFS Controller - Flight Rudder Pedals: sent event AXIS_LEFT_BRAKE_SET with value 0
2021-07-04 20:14:07 INFO  SiRunner - MSFS Controller - Flight Rudder Pedals: called with type = 0, index = 1, input = 0.0
2021-07-04 20:14:07 INFO  SiRunner - MSFS Controller - Flight Rudder Pedals: sent event AXIS_RIGHT_BRAKE_SET with value 0
2021-07-04 20:14:07 INFO  SiRunner - MSFS Controller - Flight Rudder Pedals: called with type = 0, index = 2, input = 0.0
2021-07-04 20:14:07 INFO  SiRunner - MSFS Controller - Flight Rudder Pedals: sent event AXIS_RUDDER_SET with value 0
2021-07-04 20:14:07 INFO  SiRunner - MSFS Controller - Flight Rudder Pedals: called with type = 0, index = 0, input = -1.0000305175781
2021-07-04 20:14:07 INFO  SiRunner - MSFS Controller - Flight Rudder Pedals: sent event AXIS_LEFT_BRAKE_SET with value -16383
2021-07-04 20:14:07 INFO  SiRunner - MSFS Controller - Flight Rudder Pedals: called with type = 0, index = 1, input = -1.0000305175781
2021-07-04 20:14:07 INFO  SiRunner - MSFS Controller - Flight Rudder Pedals: sent event AXIS_RIGHT_BRAKE_SET with value -16383
Now index 2 is the axis for rudder action.

After startup only axis 0 and 1 (left and right toe brakes) produce calbacks. Axis 2 does not produce any callbacks. I´m puzzled...

Tetrachromat
Posts: 236
Joined: Sun Feb 14, 2021 6:55 pm

Re: "Game Controller" does not call back on all axis

#13 Post by Tetrachromat »

Also checked the Flight Throttle Quadrant. Everything is OK.

LUA code is

Code: Select all

-- MSFS Game Controller
-- Saitek Pro Flight Throttle Quadrant

local controller = "Flight Throttle Quadrant"
local gc_id = nil

local axis = {} 

axis[0] = { event = "AXIS_THROTTLE1_SET",  range = -16383 }
axis[1] = { event = "AXIS_MIXTURE1_SET",   range = -16383 }
axis[2] = { event = "AXIS_FLAPS_SET",      range = -16383 }

local bttn = {}

-- bttn[0] = { on_press = nil, on_release = nil } -- Template
bttn[0] = { on_press = nil, on_release = nil } -- T1
bttn[1] = { on_press = nil, on_release = nil } -- T2
bttn[2] = { on_press = nil, on_release = nil } -- T3
bttn[3] = { on_press = nil, on_release = nil } -- T4
bttn[4] = { on_press = nil, on_release = nil } -- T5
bttn[5] = { on_press = nil, on_release = nil } -- T6
bttn[6] = { on_press = nil, on_release = nil } -- Reverse Lever 1
bttn[7] = { on_press = nil, on_release = nil } -- Reverse Lever 2
bttn[8] = { on_press = nil, on_release = nil } -- Reverse Lever 3

function callback(type, index, input)
  log("called with type = " .. type .. ", index = " .. index .. ", input = " .. tostring(input))
  if type == 0 and index < 3 then
    event = axis[index].event
    if event then
      output = math.floor(axis[index].range * var_cap(input, -1.0, 1.0))
      fs2020_event( event, output )
      log("sent event " .. event .. " with value " .. output)
    end
  elseif type == 0 and index >= 3 then
    if input > 0 then
      event = axis[index].inc
      if event then 
        fs2020_event( event )
        log("sent event " .. event )
      end
    elseif input < 0 then
      event = axis[index].dec
      if event then 
        fs2020_event( event ) 
        log("sent event " .. event )
      end
    end
  elseif type == 1 and index < 9 then
    if input then
      event = bttn[index].on_press
      if event then 
        fs2020_event( event )
        log("sent event " .. event )
      end
    else 
      event = bttn[index].on_release
      if event then 
        fs2020_event( event )
        log("sent event " .. event )
      end
    end 
  end
end

gc_id = game_controller_add(controller, callback)
if gc_id then
  log("Game Controller added.")
end
-- END - -- MSFS Game Controller
-- Saitek Pro Flight Throttle Quadrant

local controller = "Flight Throttle Quadrant"
local gc_id = nil

local axis = {} 

axis[0] = { event = "AXIS_THROTTLE1_SET",  range = -16383 }
axis[1] = { event = "AXIS_MIXTURE1_SET",   range = -16383 }
axis[2] = { event = "AXIS_FLAPS_SET",      range = -16383 }

local bttn = {}

-- bttn[0] = { on_press = nil, on_release = nil } -- Template
bttn[0] = { on_press = nil, on_release = nil } -- T1
bttn[1] = { on_press = nil, on_release = nil } -- T2
bttn[2] = { on_press = nil, on_release = nil } -- T3
bttn[3] = { on_press = nil, on_release = nil } -- T4
bttn[4] = { on_press = nil, on_release = nil } -- T5
bttn[5] = { on_press = nil, on_release = nil } -- T6
bttn[6] = { on_press = nil, on_release = nil } -- Reverse Lever 1
bttn[7] = { on_press = nil, on_release = nil } -- Reverse Lever 2
bttn[8] = { on_press = nil, on_release = nil } -- Reverse Lever 3

function callback(type, index, input)
  log("called with type = " .. type .. ", index = " .. index .. ", input = " .. tostring(input))
  if type == 0 and index < 3 then
    event = axis[index].event
    if event then
      output = math.floor(axis[index].range * var_cap(input, -1.0, 1.0))
      fs2020_event( event, output )
      log("sent event " .. event .. " with value " .. output)
    end
  elseif type == 0 and index >= 3 then
    if input > 0 then
      event = axis[index].inc
      if event then 
        fs2020_event( event )
        log("sent event " .. event )
      end
    elseif input < 0 then
      event = axis[index].dec
      if event then 
        fs2020_event( event ) 
        log("sent event " .. event )
      end
    end
  elseif type == 1 and index < 9 then
    if input then
      event = bttn[index].on_press
      if event then 
        fs2020_event( event )
        log("sent event " .. event )
      end
    else 
      event = bttn[index].on_release
      if event then 
        fs2020_event( event )
        log("sent event " .. event )
      end
    end 
  end
end

gc_id = game_controller_add(controller, callback)
if gc_id then
  log("Game Controller added.")
end
-- END - 
log output on startup is

Code: Select all

2021-07-04 20:43:36 INFO  SiRunner - MSFS Controller - Flight Throttle Quadrant: Game Controller added.
2021-07-04 20:43:36 INFO  SiRunner - MSFS Controller - Flight Throttle Quadrant: called with type = 0, index = 0, input = 0.0
2021-07-04 20:43:36 INFO  SiRunner - MSFS Controller - Flight Throttle Quadrant: sent event AXIS_THROTTLE1_SET with value 0
2021-07-04 20:43:36 INFO  SiRunner - MSFS Controller - Flight Throttle Quadrant: called with type = 0, index = 1, input = 0.0
2021-07-04 20:43:36 INFO  SiRunner - MSFS Controller - Flight Throttle Quadrant: sent event AXIS_MIXTURE1_SET with value 0
2021-07-04 20:43:36 INFO  SiRunner - MSFS Controller - Flight Throttle Quadrant: called with type = 0, index = 2, input = 0.0
2021-07-04 20:43:36 INFO  SiRunner - MSFS Controller - Flight Throttle Quadrant: sent event AXIS_FLAPS_SET with value 0
After startup all axis and buttons produce correct callbacks. No issues at all.

User avatar
Corjan
Posts: 2936
Joined: Thu Nov 19, 2015 9:04 am

Re: "Game Controller" does not call back on all axis

#14 Post by Corjan »

Hi,


I already was a bit unsure about my hack.

Do you maybe have time this week for me to connect to your computer remotely, so we can do some debugging together.
I cannot really do that here since I don't have the hardware you have.


You can contact me at 'corjan@siminnovations.com',

Corjan

Tetrachromat
Posts: 236
Joined: Sun Feb 14, 2021 6:55 pm

Re: "Game Controller" does not call back on all axis

#15 Post by Tetrachromat »

Yes that is possible. This week Friday would be fine.

User avatar
Corjan
Posts: 2936
Joined: Thu Nov 19, 2015 9:04 am

Re: "Game Controller" does not call back on all axis

#16 Post by Corjan »

Hi,


I think (hope) that I fixed it.
Luckily, there is a way to distinguish between a rudder and joystick.

There is a new BETA online right now. Would you mind testing with that version?


Corjan

User avatar
jph
Posts: 2846
Joined: Fri Apr 10, 2020 12:50 pm
Location: Somewhere over the rainbow..

Re: "Game Controller" does not call back on all axis

#17 Post by jph »

Corjan wrote: Fri Jul 09, 2021 2:00 pm Hi,


I think (hope) that I fixed it.
Luckily, there is a way to distinguish between a rudder and joystick.

There is a new BETA online right now. Would you mind testing with that version?


Corjan
Hi Corjan. Question.. why would you want to distinguish between a rudder and a joystick ?. Is it not the case where the actual axis is the important thing ?
I know have seen options in USB descriptors for axis for a naming convention but they seem to be hardly ever used - certainly for the first 6 axis. Most are simply assigned in the sim or else come pre-assigned in the sim to certain pre-programmed devices.
Interesting.
Joe
Joe. CISSP, MSc.

User avatar
Corjan
Posts: 2936
Joined: Thu Nov 19, 2015 9:04 am

Re: "Game Controller" does not call back on all axis

#18 Post by Corjan »

Hi,

For joysticks, the last 2 axis are a bit misused for the hat switch it seems.
So in the code you have to process the axis data a bit different, depending on what kind of device class it is.

Corjan

User avatar
jph
Posts: 2846
Joined: Fri Apr 10, 2020 12:50 pm
Location: Somewhere over the rainbow..

Re: "Game Controller" does not call back on all axis

#19 Post by jph »

Hi Corjan,
If I remember correctly, the 'generic' joystick class usually has the 8 axis as X, Y, Z, rX, rY, rZ, Dial and Slider. Then the Hat(s) - up to 2 . are treated differently but don't occupy the space of the Dial and Slider ? - I did a bit quite a lot of work with a PIC HID Joystick descriptor about 10 years ago so am going from that - it was a while back though.. :)

I know there are various other 'specific' 'game controller' options apart from the USAGE_PAGE (Generic Desktop) and USAGE(Joystick) that seem to specifically name items such as 'rudder' 'throttle' etc - as in game controller iirc (that were designed to be recognised as named - ie - wheel, throttle, rudder, flight control (or similar) etc etc). I experimented with them and then quickly gave up as they were too specific and designed for a different era where it was 'hoped' that a device could be plugged in and 'recognised' without anything being set up in the game. I believe that quickly went out of fashion due to built in user selectable axis / game assignments and manufacturer's intermediate software. ?
I thought that the 'hat'(s) remained the same if using the above generic page and usage settings ?.. although, I must confess I have done little with the HID stuff for 10 years - but I DID do some work on the Arduino 'Joystick' lib and descriptor to get rid of all but the generic USAGE(Joystick) stuff. I believe that the only 'named' axis were dial and slider. hence the XYZ and r XYZ D S + 32 buttons and two hats. I still have this somewhere.
Are you using the generic Joystick ?
Thanks, this brings back memories - some not so good with HID, some quite traumatic :o haha.

Joe
Joe. CISSP, MSc.

Tetrachromat
Posts: 236
Joined: Sun Feb 14, 2021 6:55 pm

Re: "Game Controller" does not call back on all axis

#20 Post by Tetrachromat »

With the new BETA, my SAITEK Flight Yoke System is working properly now, including the hat switch (axis 5 and 6).

SAITEK uses the same scheme (axis 6 and 7) for the second hat switch on the "Saitek X52 Pro Flight Control System".
The primary hat switch is using 4 "buttons" (23...26). This scheme allows to save two buttons or circumvent the 32 buttons limit, as is the case in the X52.

BUT, the SAITEK Rudder Pedals still has an issue with the rudder axis.
Left toe brake axis (index = 0) and right toe brake axis (index = 1) are ok.
Rudder axis (index = 2) does report on startup with value 0.0, but any action on the rudder pedals won't call back.
log_rudder_pedals.txt
(45.58 KiB) Downloaded 149 times

Paul

Post Reply