2015-12-16

K-42 Part 9: Python server and joystick library progress

I've made some progress on the server part.

The implementation for networked clients I wrote about in part 8 is mostly done. A useful feature I added was support for broadcasts server announcements on the local network and automatic connection (and reconnection) of clients on both serial ports and network ports. I no longer have to restart the server if I disconnect a client temporarily which makes it simpler when debugging my programs.

I have vague plans on removing the automatic reconnect again a a later time as I would prefer to do the reconnects manually. I want an SCE to AUX switch to use when communication fails. On the other hand, robust automation is also a nice feature so we'll see what I decide.

The server is still a one way street. Presently it can receive only handshake messages and it would be nice to add support for clients to send commands to both KSP and each other through the server, but that will have to wait until later as I don't have any need for two way communication yet.

Another thing I've been working on is the joystick emulation. I used two arduinos (a Leonardo and a Pro Mini) to emulate two joysticks. The reason was that my joystick library only supported six axes and 32 buttons and I needed seven axes and 40 buttons for my console. When I decided to upgrade to Arduino IDE 1.6 last week it was also time to upgrade Matthew Heironimus joystick library to a new and improved version, and as I did that I also decided to fork off the joystick library and create my own KSP-centric version for my control panel.

My first plan was to create two identical joysticks, each with six axes and 32 buttons and just move all the joystick code in the Pro Micro. Should be easy enough I thought. Problem was that even though KSP can differentiate between buttons and axes on two different USB devices, it get confused when they are all on the same device. The buttons all worked fine, but I had no joystick controls. After a little reading of the USB specification I found that I could easily add more axes by defining slider controls, and it was logical too as the throttle is a slider control. Yes! I could define a working seven axis joystick.

There was still the problem with the need for more buttons however. It would be easy to define 48 or 64 buttons in the USB descriptor but it's unlikely that Windows would handle it. The game controller settings in Windows only have support for testing up to 32 buttons and Action Groups Extended mod couldn't handle more that 20 buttons per joystick anyway. I decided to solve the problem by defining a second joystick without any control axes at all, just 32 buttons. I was a little weird but USB is flexible and KSP actually could handle the buttons on that "joystick". But there was one big problem still...

KSP could still not handle axes when two joysticks were defined even though the second one didn't have any to be confused by. Time for the next workaround. Almost back to square one, I defined two identical joysticks again, but with the difference that all joystick axes reported identical values all the time by using global variables to store the values. This actually solved my problem as it now doesn't matter which joystick KSP reads, they all give the same reading and everything works as intended. Phew!


Maybe I'll actually play the game for a while during the holidays instead of just building custom  controls... Naaaaah! Probably not. :-)

Edit: When I tried to play I found that the joysticks had stopped working again. The reason proved to be the simple fact that I had defined three joysticks in the USB HUD user page definition but initialized only two of them. Of course KSP/Unity had found the uninitialized one this time and decided to poll that one for axis input instead of the one I used in the settings screen. Everything worked again when I removed the extra unused joystick from the USP definition. We'll see how long it works this time.