Is there a "generic" gamepad event for "SOMETHING happened"?


I hope this finds you safe and well.


I am trying to develop a web app, (combination html and javascript), to control a robot with a joystick.

N.B. I don’t understand why, but there doesn’t seem to be ANY code or examples for using an actual joystick to control a server-side “thing”. It’s all “virtual joysticks” like nipple.js, etc.

Right now my code is organized like this:
(This is a very high-level overview)

  • Event handler for “gamepad connected”
  • Event handler for “gamepad disconnected”
  • Request Animation Frame(poll the gamepad)
    • Gamepad Polling Logic
      This grabs data from the gamepad, does some minimal logic testing so that the data makes sense, (X and Y axis values don’t matter if the robot isn’t moving), and updates values that are - for the time being - placed on the browser screen as an overlay.

If I understand correctly, the “Request Animation Frame” function calls my gamepad polling logic once every v_sync interval which is a LOT of activity, especially if I am going to be transmitting data over a network to a wireless robot.

What I’d really like to do is something like this:
(syntax may not be correct, this is psudo-code to demonstrate what I am trying to do.)
window.addEventListener (gamepad.event), such that “gamepad.event” would return whatever the event is.

For example:

    window.addEventListener (gamepad.event) {
        if (gamepad.event == "gamepadconnected"
            gamepad connected logic
        elseif (gamepad.event == "gamepaddisconnected")
            gamepad disconnected logic
            Poll for gamepad data changes
            and send updated data to the robot

This way I ONLY send data to the robot if there is something worth sending.

I’d really rather not send data 60 times a second, (or whatever), if I don’t have to because that is wasteful of bandwidth, is totally unnecessary, and complicates things on the robot’s end.

Is this possible?  Does this exist?

Corollary question:
If that does NOT exist, how do I go about throttling the data such that I only send data of interest to the robot?  (i.e. Only if the data is changing - a joystick axis value change, a button press, etc.)  I really don’t want to send 20,000 “trigger-pressed” messages to the robot if I don’t have to.  :wink:

My continuing research indicates that the correct answer is “no”, however you can synthesize a “generic” event by using the gamepad’s timer.

For example, here’s my “did_something_happen” function

function did_something_happen(jsdata, gopigo3_joystick) {
   old_time = gopigo3_joystick.time_stamp
   while (old_time == Number.parseFloat(jsdata.timestamp).toFixed()) {

And how I call it:

function  get_gamepad_data() {
  js = (navigator.getGamepads && navigator.getGamepads()) || (navigator.webkitGetGamepads && navigator.webkitGetGamepads());
  collate_data(js[0]);  //  Collect variable data to be sent

  what_am_i_doing(gopigo3_joystick)  // Collect motion status

  send_data(gopigo3_joystick);  // Send normalized data to 'bot'

  // Update the on-screen data with the nrmalized data

  //  We've sent the data, now wait for the next event to happen
  did_something_happen(js[0], gopigo3_joystick);

  // Here we loop on the requestAnimationFrame after a timeout (in ms)
  // to prevent saturating the network every 1/60th second (or faster)
  // depending on the capabilities of the monitor/browser being used.
  setTimeout(get_data, 125);

As you can see, the main loop collects gamepad data, collates it, normalizes it into a form I can send off to the robot via a POST request, and then waits for the timer to change indicating something else has happened.

The only problem with this method is that a noisy axis or button on your controller will totally defeat the purpose of this way of waiting, as “something” (noise) is always happening.

The one objection I have to this method is that it’s essentially a “spin-lock” that causes the JavaScript to “spin” until something else happens. I am not sure what the effect on the performance of the browser - especially other windows - would be but I really don’t like spinning to wait.

If anyone else has a better idea, I’d really like to hear it.

Related: How to create an enhancement request for the Gamepad API?

1 Like