2016-08-28

K-42 The Next Generation

After a long timeout I decided to stop playing the game and build stuff for it again.
As always, It's only after you've built something that you know how i SHOULD have been done.
So I decided to do a few modifications of the K-42 command console. The first modification was to scrap the whole design, except the enclosure, the I2C bus and the keyboard, and start all over again.
System architecture and communication
The original system was designed as single master, multiple slaves. There would be one master doing all the processing stuff and the slaves would only answer to polling requests. The master would also be responsible for emulating USB joystick and serial port. Every module had its own protocol format and its own fixed length message.
There was several problems with this design:
  • The whole system had to fit into 25kB of free program memory and the computational constraints of a 16MHz 8-bit processing capacity of a single Arduino.
  • The master needed information about every module and what is was supposed to do.
  • The master had to poll every module every 20 ms, even if nothing changed, in order to get low latency joystick position information.
The new architecture is a pure multi master network with a message based communication protocol. This means that if the state of a module changes, it just send a message of the state change to all listeners. Each message is composed of two bytes, a property and a value.
The advantages with the new design is:
  • There is no theoretical limit to the amount of processing nodes which eliminates the need for bigger memory and faster CPU. If there are many tasks or long computation, they can be distributed to more processors. Communication bandwidth will be the limiting factor.
  • Each module only need to hold a state of the signals that are needed to accomplish its own tasks.
  • Each module only sends state changes when something happens that is interesting for other modules. If nothing happens or if the state change is only internal, nothing is sent.
Computer interface
The original plan was to use mods for extra action groups to increase the number of controls. All switches would be mapped to unused key combinations and I would use arduinos keyboard library to send Alt, Shift and Ctrl key combinations for each action. These key combinations would in turn be mapped to action groups and those would be mapped to actions of different parts of the space ship.
I wish I had written this down before I started building the damned thing. In that case it would have been obvious that the amount of mapping key combinations to action groups to parts, would take most of the time used for building a new craft. Now I could happily discover that little detail after building and programming most of the modules instead.
The new plan is much simpler:
  1. Build a “joystick” that implements basic KSP controls for manual flying. Connect it as a USB joystick with buttons and map those using the built in control mappings in KSP.
  2. Build instrumentation that can display some basic stuff like altitude, speed, apoapsis and the like.
  3. Build some kind of navigation computer that can help with burn timing, soft landings and getting into orbit in a reasonably efficient way.
The parts above will be built and tested independently from each other, limiting the amount of reworking needed if I have a bad brain day or is just plain unlucky when trying to think. There is no actual need to build the in that specific order either, but I decided to make the manual controls first, because of reasons. I don’t know yet what the next step will be.
Coming soon™
The manual controls; HID, electronic and program design. Stay tuned.

2016-02-09

K-42 Part 10: Timeout

Ok, no posts for a long time.

I've been doing some play testing and things have screwed up big time.
  • The controls work fine.
  • The Python server works ok most of the time.
  • The displays that has been implemented so far works fine.
  • The game lags like hell.
The problem is that it lags a bit even when I disconnect everything and just run the kRPC server. The problem is either in the KSP installation, the save, the kRPC installation or my computer hardware specs. I've checked with others on the forum and they don't seem to have the problem, at least not on a clean install.

I have worked on this a lot in my available spare time and was looking forward to continue my quest for the outer planets using my new control panel, but noooo...

So instead of pushing myself to the brink of rage quit, I'll take a timeout. It may take a couple of months to regain enthusiasm and inspiration but I'll be back.

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.