Jump to content

[KSP 1.10.0] Kerbal Simpit: A KSP serial mod for hardware controllers (1.4.1)


stibbons

Recommended Posts

8 hours ago, Freshmeat said:

I got a mock up to work with Win 7 and a Due, just sending some simple telemetry.

Excellent news! Thanks for letting me know.

8 hours ago, Freshmeat said:

I consider rebuilding my controller (again), using WS2812 led strips instead of MAX7219 for annuciators

You can buy WS2812 LEDs in a regular 5mm through-hole housing (Sparkfun has them, can probably be found cheaper from eBay/aliexpress/etc. I used those for all of the lights in my board, including the annunciator, with great success.

8 hours ago, Freshmeat said:

Coming from KSPSerialIO, the code structure takes a little change of mindset,

Yep, that was intentional. Simple projects become trivially simple. In theory more complicated stuff is possible, but it looks like I still have a fair amount of work to do on the Aruidno library to make it run smoothly. :/

8 hours ago, Freshmeat said:

so it can take a while before I get around to bother you with questions and requests.

I know the feeling. My maker space took on a commission for an event at the local museum, so I've been flat out working on building our project for that. It'll be another week or two before I'm able to get back in to hacking on this project. :(

 

Link to comment
Share on other sites

  • 4 weeks later...

After a month off working on other projects (and, it must be said, getting a little lost in Breath of the Wild), I'm easing back in to KSP and hacking on this mod.

Testing pulling several channels and doing (light) work on a mega I'm unable to reproduce any issues with the Arduino library. It seems as solid as can be. So I'm not going to worry any more about bug fixing in the Arduino library for the next little while.

Currently working on enhancing how the plugin schedules data to be sent to devices. Right now all data providers are run, in a fixed order, whether they're actually sending to a device or not. For the next release I'd like each serial device to be able to track what it's subscribed to, in the order it subscribed, and only run data handlers for those subs. I'm hoping this will help spread channel updates out over the refresh period, because right now it's way too easy to inadvertently bunch everything together.

Link to comment
Share on other sites

Hi!

2 hours ago, Scout1218 said:

Can this plugin toggle fine controls?

Not yet. I'll get to adding fine control toggle at some point, but at the moment I'm focussing more on less visible work making the internals more stable.

For what it's worth, I keep track of everything I've got in progress and planned on a trello board: https://trello.com/b/t6YUftuS/kerbal-simpit-progress . 

Edited by stibbons
Link to comment
Share on other sites

4 hours ago, Scout1218 said:

Okay, Is there anyway I can add that in myself?

Adding a handler for that should be relatively simple, especially if you've done any work playing with KSP plugins before. The only concern is that my current workflow relies on tools that only really exist in Linux, and there's probably some extra work required before you can make the code build using Visual Studio or similar.

If you're interested in trying it out, the source code for the plugin lives at https://bitbucket.org/pjhardy/kerbalsimpit . You'll find some details about how to configure your IDE to build the project, as well as how to structure a new class to send or receive data, at https://bitbucket.org/pjhardy/kerbalsimpit/wiki/PluginHacking.md .

Link to comment
Share on other sites

  • 4 weeks later...

Just pushed a very small plugin update with version 1.3.1 compatibility.

Untested, as I'm at work right now and in the middle of some fairly big changes at home that will keep me occupied for the next few weeks. But if the build passes successfully I have no reason to doubt it'll work OK.

Link to comment
Share on other sites

  • 2 weeks later...
  • 3 months later...

Two questions: one, have you given any thought to including data on commlink status to KSC?  I would love to be able to add red/yellow/green LEDs to a probe control panel.

Second, I cannot find any information on the message format for main vessel throttle control beyond

Quote
THROTTLE_MESSAGE = 19

Send vessel throttle commands.

I don't see any information on an appropriate structure for sending throttle commands.  throttleMessage does not appear to be a thing.  I have done my best to crawl the source and find something, but no dice.  Any guidance?

Link to comment
Share on other sites

Apologies for the delayed response. I'm still on holiday, a very long way away from all of my KSP stuff. :D

On 22/12/2017 at 6:43 PM, commissar_squid said:

Two questions: one, have you given any thought to including data on commlink status to KSC?  I would love to be able to add red/yellow/green LEDs to a probe control panel.

I had not thought of that at all, mostly because I use RemoteTech instead of the stock commnet. No idea how feasible that will be, yet. Just added a card for it to my backlog on the Trello board for this project, will poke around it again when I'm back home in a few weeks. 

On 22/12/2017 at 6:43 PM, commissar_squid said:

I don't see any information on an appropriate structure for sending throttle commands.  throttleMessage does not appear to be a thing.  I have done my best to crawl the source and find something, but no dice.  Any guidance?

Sorry. I've had plans for a while to make those docs a little more concise. 

When there's no message struct, you can assume that the payload is a single basic data type. For a throttle command, the payload should be a plain `int`, that is, an `int16_t`. 

And, for what it's worth, I dug that up just now by looking through the c# source code for the game plugin, all of the nitty gritty of interfacing with the game API can be found in the Providers directory of https://bitbucket.org/pjhardy/kerbalsimpit

Link to comment
Share on other sites

On 12/27/2017 at 10:30 PM, stibbons said:

Apologies for the delayed response. I'm still on holiday, a very long way away from all of my KSP stuff. :D

I had not thought of that at all, mostly because I use RemoteTech instead of the stock commnet. No idea how feasible that will be, yet. Just added a card for it to my backlog on the Trello board for this project, will poke around it again when I'm back home in a few weeks. 

Sorry. I've had plans for a while to make those docs a little more concise. 

When there's no message struct, you can assume that the payload is a single basic data type. For a throttle command, the payload should be a plain `int`, that is, an `int16_t`. 

And, for what it's worth, I dug that up just now by looking through the c# source code for the game plugin, all of the nitty gritty of interfacing with the game API can be found in the Providers directory of https://bitbucket.org/pjhardy/kerbalsimpit

Thank you for the help and for the great plugin!  I will hack around and see if I can figure it out.

One more suggestion I might make, if its doable, would be to be able to address SAS mode (prograde, target, node, etc).  I am planning to put a 10-position rotary switch on my panel to select those, and at the moment the only way I can think to do it is to use Diazo's ModActions to assign SAS mode to custom action groups, copy the custom groups to each ship, and trigger the groups via toggleCAG.  It works, but it's a bit of a hassle.  

Also, enjoy your vacation.  :)

Link to comment
Share on other sites

  • 2 weeks later...
  • 2 weeks later...

Excuse me,I try sending the THROTTLE_MESSAGE(19),but it doesn't work. At the same time ,rotation message works well. I used the func send(19,data,2) . My KSP Version is 1.3.1.1891. And I used a arduino nano and a crystal Liquid to decode the PPM signal and send the control message by serial and show attitude on screen. Everything worked well except the throttle.  Is there any solutions?

Link to comment
Share on other sites

  • 1 month later...
On 24/01/2018 at 3:17 AM, EricccMa said:

Excuse me,I try sending the THROTTLE_MESSAGE(19),

Sorry, I've only just now saw this.

Life has been busy, and I haven't had much time for working on side projects. But with the 1.4 drop I'll be doing a little work getting this updated. Will look closer at your problem soon.

Would you wind sharing a little of the code you're using?

Link to comment
Share on other sites

With apologies for the long delay - KSP 1.4 dropped without warning the day before I went away for a short holiday, and I had to do a lot of work getting my build server functional again. But I've just uploaded version 1.2.3 of Kerbal Simpit, which has been built for KSP 1.4.0. The CKAN robot should pick it up shortly.

Build server is working again, so I promise an update for 1.4.1 will be much faster. :) 

Link to comment
Share on other sites

Of course Ok. It's just a simple code modified from example. Here is the code.

 

/* KerbalSimpitHelloWorld
   A very barebones Hello World sketch, that doesn't require
   any extra hardware. It periodically sends EchoRequest packets
   to the game, and uses the EchoReply packets to switch the
   on-board LED on and off. Note that the game only activates the
   echo handler during the flight scene.
   Great for confirming basic connectivity.

   Peter Hardy <peter@hardy.dropbear.id.au>
*/
#include "KerbalSimpit.h"
#include <Arduino.h>
#include <LiquidCrystal.h>
#include <PayloadStructs.h>
// Declare a KerbalSimpit object that will
// communicate using the "Serial" device.
KerbalSimpit mySimpit(Serial);

// This boolean tracks the desired LED state.
bool state = false;
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 6;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

altitudeMessage altitude;

// A timestamp of the last time we sent an echo packet.
unsigned long lastSent = 0;
// How often to send echo packets (in ms)
unsigned int sendInterval = 100;

int firstTimeFlag=1;
int receivedFlag=0;

void messageHandler(byte messageType, byte msg[], byte msgSize) {
  // We are only interested in echo response packets.
  if (messageType == ECHO_RESP_MESSAGE) {
    // The message payload will be either "low" or "high".
    // We use the strcmp function to check what the string payload
    // is, and set the LED status accordingly.
    if (msg[0]=='l') {
      digitalWrite(LED_BUILTIN, LOW);
    } else {
      digitalWrite(LED_BUILTIN, HIGH);
    }
  }
  if(messageType == ALTITUDE_MESSAGE)
  {
	  altitude=parseAltitude(msg);
	  if(firstTimeFlag)
	  {
		  lcd.clear();
		  lcd.print("R-ALT");
		  firstTimeFlag=0;
	  }
	  lcd.setCursor(0,1);
	  lcd.print(altitude.surface);
	  receivedFlag=1;
  }
  if(messageType==SCENE_CHANGE_MESSAGE)
  {
	  firstTimeFlag=1;
	  receivedFlag=0;
	  altitude.surface=0;
  }
}

int RC1[10]={1506,1506,1506,1506,1506,1506,1400};
int16_t RC[4]={0};
void parseRC()
{
	for(int i=0;i<4;i++)
	{
		RC[i]=map(RC1[i],1100,1900,-97,97);
		RC[i]=map(RC[i],-97,97,-31000,31000);
	}
}
void InterruptService()
{
	static unsigned long int lastTime=0;
	static int cursor=0;
	if (digitalRead(2) == LOW)
	{
		unsigned long int now=micros();
		unsigned long int thisTime=now-lastTime;
		if(thisTime>3000)
		{
			cursor=0;
		}else
		{
			RC1[cursor++]=thisTime;
		}
		lastTime=now;
	}
}

void setup() {
  // Open the serial connection.
	pinMode(2,INPUT);
	attachInterrupt(0,InterruptService,CHANGE);

  Serial.begin(115200);
  lcd.begin(16, 2);
    // Print a message to the LCD.
  lcd.print("Connecting...");
  // Set up the built in LED, and turn it on.
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  // This loop continually attempts to handshake with the plugin.
  // It will keep retrying until it gets a successful handshake.
  while (!mySimpit.init()) {
    delay(100);
  }
  // Turn off the built-in LED to indicate handshaking is complete.
  digitalWrite(LED_BUILTIN, LOW);

  mySimpit.registerChannel(ALTITUDE_MESSAGE);
  mySimpit.registerChannel(SCENE_CHANGE_MESSAGE);
  lcd.clear();
  lcd.print("  #Connected#");
  lcd.setCursor(0,1);
  lcd.print("Waiting Data...");
  // Sets our callback function. The KerbalSimpit library will
  // call this function every time a packet is received.
  mySimpit.inboundHandler(messageHandler);
}

void loop() {
  unsigned long now = millis();
  // If we've waited long enough since the last message, send a new one.
  if (now - lastSent >= sendInterval) {
	  if(receivedFlag)
	  {
		  parseRC();
		  rotationMessage rotationMsg;
		  rotationMsg.mask=1|2|4;
		  if(RC1[4]>1500)//Manual
		  {
			  rotationMsg.roll=RC[0];
			  rotationMsg.pitch=RC[1];
			  rotationMsg.yaw=RC[3];
			  lcd.setCursor(11,0);
			  lcd.write("MAN ");
		  }else
		  {
			  rotationMsg.roll=0;
			  rotationMsg.pitch=0;
			  rotationMsg.yaw=0;
			  lcd.setCursor(11,0);
			  lcd.write("AUTO");
		  }
		  mySimpit.send(ROTATION_MESSAGE,rotationMsg);
		  RC[2]+=3000;
		  RC[2]=RC[2]<0?0:RC[2];
		  RC[2]=map(RC[2],0,6000,0,1000);
		  mySimpit.send(THROTTLE_MESSAGE,(unsigned char*)(&RC[2]),2);
	  }else
	  {
		lcd.setCursor(0,0);
		lcd.print("  #Connected#  ");
		lcd.setCursor(0,1);
		lcd.print("Waiting Data...");
	  }
  }
  // Call the library update() function to check for new messages.
  mySimpit.update();
}

here

		  mySimpit.send(ROTATION_MESSAGE,rotationMsg);
		  RC[2]+=3000;
		  RC[2]=RC[2]<0?0:RC[2];
		  RC[2]=map(RC[2],0,6000,0,1000);
		  mySimpit.send(THROTTLE_MESSAGE,(unsigned char*)(&RC[2]),2);
	  }else

Everything works well except the throttle. I just test on KSP1.3.1. About  KSP 1.4, I haven't test because have no radio controller this time. 

Link to comment
Share on other sites

@EricccMa Wait, are you using an RC transmitter to control KSP? That's really awesome. :D

	for(int i=0;i<4;i++)
	{
		RC[i]=map(RC1[i],1100,1900,-97,97);
		RC[i]=map(RC[i],-97,97,-31000,31000);
	}

So the values you're reading from the controller are in the range 1100-1900, and you're mapping that to the full range of a signed 16 bit int. That's fine.

		  RC[2]+=3000;
		  RC[2]=RC[2]<0?0:RC[2];
		  RC[2]=map(RC[2],0,6000,0,1000);

Are you sure you want to be discarding negative values of RC[2]? I don't know how your controller behaves, but I do know that the throttle on my Logitech USB joystick uses the full 16 bit range, so "throttle off" is actually -32767.

Finally, I'm not sure of the impact of using the map function when the input is outside the specified range. But I think you're effectively dividing the throttle value by 6? That could end up lower than you'd expect.

The plugin treats the throttle data the same as the pitch/roll/yaw data, with the exception that negative values are ignored. So send a 0 for throttle off, and 32768 for full throttle. I'm worried that second block altering RC[2] ends up setting it to a value that is too low to be useful. Maybe try writing the throttle value to your LCD before sending it as well to confirm it's giving decent data.

Unfortunately my test hardware rig is still in a box somewhere after a recent move, so still getting my life back to the point where I can put decent time in to investigating this and doing serious development on the plugin. But it's getting there!

Edited by stibbons
Link to comment
Share on other sites

So I just started out with custom KSP controllers and ran into a similar issue regarding the throttle.

I'm using KSP 1.4.1.2089, with Simpit 1.2.4.53 and Arduino library version 1.1.3 . I have turned verbose logging on.
 

My code regarding the issue boils down to the following:

int16_t val = 32767; // At this point this is just a static value
simpit.send(THROTTLE_MESSAGE, (unsigned char*) &val, 2);

Action groups work just fine (activating, deactivating, toggling). AG actions also lead to according debug output in the KSP console.

Sending the message above however doesn't give any message in the debug console inside KSP. The issue seems to be on the KSP end, as the message seems to be sent successfully (as indicated by a flickering TX LED).
 

Maybe I'm not seeing it, but an even more verbose output, that would also log failed transmissions and such, would be helpful.

Link to comment
Share on other sites

57 minutes ago, 0xDiddi said:

So I just started out with custom KSP controllers and ran into a similar issue regarding the throttle.

Thank you for confirming it. I'll take a closer look when I'm home from work this evening.

57 minutes ago, 0xDiddi said:

Maybe I'm not seeing it, but an even more verbose output, that would also log failed transmissions and such, would be helpful.

Better logging is already on my todo list for the next (real) release, the fact that people apart from me are starting to use this plugin is pretty good motivation to do some more work on it soon. :) 

Link to comment
Share on other sites

15 hours ago, 0xDiddi said:

So I just started out with custom KSP controllers and ran into a similar issue regarding the throttle.

Mea culpa. I didn't properly test the throttle handling after adding it, so of course it was hideously broken. :(

I've fixed the handler so that the plugin is at least able to receive and process throttle packets. But working my test rig (a 10k potentiometer hooked up to an arduino :) ) I was still getting erroneous values. Unfortunately I'm going to have to bust out the logic analyser to get to the bottom of that.

But in the interest of releasing early and releasing often, version 1.2.5 is now out.

  • Throttle packets are now received and handled. Probably incorrectly. :(
  • With "verbose" set to true in the config file, the plugin will log the contents of every throttle packet received.

Work is still progressing on the throttle, after that I'd like to make the handlers and their logging a little bit more robust. Don't expect to be adding very many user-visible features on the plugin end for the next little while, sorry.

And adding insult to injury, it looks like the Arduino Library Manager updater hasn't been crawling new releases of the Simpit Arduino library. Right now installing through the Library Manager will get you version 1.0.0, while the most recent is 1.1.3 (and is definitely worth using instead). Still trying to get to the bottom of what's wrong, but the best I can suggest right now is making sure you install the library from https://bitbucket.org/pjhardy/kerbalsimpit-arduino/downloads/kerbalsimpit-arduino-1.1.3.zip

Link to comment
Share on other sites

8 hours ago, stibbons said:

Throttle packets are now received and handled. Probably incorrectly. :(

With my setup (that until my order arrives only consists of a 3-state switch), it works just fine: switching between 0, 50 and 100% throttle.

With that now I could even launch a small satellite into orbit. All that's missing for complete control (at least in my book) now is switching of SAS modes (prograde, retrograde, hold, ...).

If someone knows a mod that lets you assign SAS modes to action groups that would however work just as well (I couldn't find a working solution with some quick googling).

Link to comment
Share on other sites

1 hour ago, 0xDiddi said:

With my setup (that until my order arrives only consists of a 3-state switch), it works just fine: switching between 0, 50 and 100% throttle.

Great to hear that's working properly. Keen to see how you get on with the full setup. :)

1 hour ago, 0xDiddi said:

All that's missing for complete control (at least in my book) now is switching of SAS modes (prograde, retrograde, hold, ...).

Soon. 

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...