With the board almost up and running (and a vacation coming up with little access to the shop), I'm starting to think more intensely about software design. For those of you who haven't done this research, there are at least 5 basic approaches, with the additional possibility of combining them. Unfortunately it can be hard to get concrete information about both the capabilities of these solutions (because so many people modify them; e.g. KSPSerialIO has 38 forks on github), and their performance (because it varies with quality and complexity of implementation). The result is that I've ended up trawling the forums for definite guidance and ended up with a lot of hearsay.
So before I actually write any code, it's worth laying out in detail what capabilities I'll need so I can approach implementation in a structured way (knowing that any of these are going to take a LONG time to implement, so better not resort to trial and error.
Here's a table of our features and which solutions can accomplish them (at least, in principal). This is just what I need from the plugin / interface with KSP: some controls are managed solely in code I'll write, like throttle limiting. Also: these are all complex projects, so take these with a grain of salt:
|What do||kRPC?||Joystick Emulation?||KerbalSimpit?|
|Switch Map Target||?||✅||❌|
|Switch SAS Mode||✅||❌*||✅|
|Increment Warp and P. Warp||✅||✅||❌|
|2 Custom Axis Groups||❌ (maybe through wheel steer/throttle axis)||✅||❌ (maybe through wheel steer/throttle axis)|
|3 Axis Translation Control||✅||✅||✅|
|10 Action Group Buttons||✅||✅||✅|
|Rotate / Pan / Zoom Camera||✅||✅||❌|
|Select Camera Mode||✅||❌*||❌|
|Select velocity display mode|
|3 Axis Attitude Control||✅||✅||✅|
|Output Fuel/Electric/Xenon level - Stage and Vessel||✅||❌||✅|
|Output Change in Resources||?||?||?|
|Output RCS, Gear, Brakes status||✅||❌||✅|
|Output Current Selected SAS mode||✅||❌||✅|
|Output Vessel Supported SAS modes||❌|
(maybe with part detection)
|Output Vessel Type Info (maybe)||✅||❌||❌|
*: a mod on top of joystick control might accomplish this.
I didn't consider KSPSerialIO, as it's a bit harder to find documentation for (and, as I've said, has been extensively forked). It does have some cool features (for example, it can set the navball speed display mode).
Features are good, but performance is everything. This is meant to be a HID experience, and people can detect imput lags as small as 1ms, so the system needs to be high performing.
Arduino to python is, in my view, unlikely to be a bottleneck. With no compression, we are transmitting no more than 64 bits (8 bytes) of binary switch data, 13 axes (another 13 bytes at 256 resolution), and are receiving 2 bytes of LED data, and about 6 of miscellaneous other information. That's 29 bytes per transaction, call it 50 with fudge factor. If we wrote the most inefficient system possible, that would mean we'd need to transmit 50kbytes p/second (or 50,000 baud) with 1000 transactions p/s, which is well within the capabilities of our chip. We're gonna figure out a way to get that done. Performance issues really come in when we talk about communicating to the game.
At first glance at the above, kRPC is a no brainer. The Krpc documentation describe that the mod makes updates every game tick, and you can set it up to either yoke KSP performance to the mod OR minimize the number of server calls it can make per second to minimize lag. There is a wait time where Krpc is listening between calls, so with complexity lag will increase (I imagine this is especially true for inputs like analog axes, which are more likely to be constantly updated). That matches the word on the street, which is that KRPC is laggy with controllers with a lot of complexity (which is understandable, because kRPC is not a controller mod: most of the people who use it are building autopilots).
BUT there's no escape: we need some kRPC features. So what we probably need to do is use more than one system. kRPC can handle anything that requires only occasional updates (e.g. action groups), and possibly data output.
We could probably use joystick input or simpit for the rest, BUT we have SOO many axes. Windows joystick drivers only support up to 8, so we'll need to represent at least 2 joysticks to the OS (and I'm not sure that Kerbal actually supports that many without Advanced fly by wire).
I don't have much information about whether simpit or advanced fly by wire will be more performative. I've heard doubts expressed about joystick support, but I'm not sure if they consider advanced fly by wire. I also don't know whether simpit is set up such that we could talk to both krpc and simpit from one device, and I'm fairly certain we could do that with the joystick, because one arduino can represent multiple joystick devices. So my current plan is joystick and kRPC: we'll just see whether that works!