A port of KSP SerialIO and KSP Ethernet IO designed for a Nucleo F746ZG. This version doesn't read from or write to any external controls or displays but the user can press the USER_BUTTON to change the status of SAS and RCS. A final version of this project with full documentation and external hardware support is coming. This is an Alpha release.
Dependencies: F7_Ethernet mbed mbed-rtos
Diff: main.cpp
- Revision:
- 16:0eda62f0d9e8
- Parent:
- 15:03ed24574806
- Child:
- 17:00d66e5edf58
--- a/main.cpp Sat Mar 14 01:33:34 2020 +0000 +++ b/main.cpp Sun Mar 15 04:35:51 2020 +0000 @@ -2,187 +2,242 @@ #include "EthernetInterface.h" #include <mbed.h> #include "Thread.h" + /* ---------------------------------------------------------------------------------------- */ #define PORT 2342 -#define DEBUG 1 +#define DEBUG 0 +#define OUTPUTENABLE 0 #if DEBUG #endif -/* -void makePacket(char *Payload,char *Packet) -{ - char Header1 = 0xBE; - char Header2 = 0xEF; - int checksum = sizeof(*Payload); - - *Packet[0] = Header1; - *Packet[1] = Header2; - *Packet[2] = sizeof(*Payload); - - for (int i = 0; i < *Packet[2]; i++) - { - checksum ^= *Payload[i]; - *Packet[i+3] = *Payload[i]; - } - *Packet[sizeof(*Packet)-1] = checksum; - } -*/ + +//pins for LEDs +#define GLED 5 +#define YLED 6 +#define RLED 7 +#define SASLED 11 +#define RCSLED 12 +#define CG1LED 13 + +//pins for input +#define SASPIN 8 +#define RCSPIN 9 +#define CG1PIN 10 +#define THROTTLEPIN 0 + +#define THROTTLEDB 4 //Throttle axis deadband + +//Input enums +#define SAS 7 +#define RCS 6 +#define LIGHTS 5 +#define GEAR 4 +#define BRAKES 3 +#define PRECISION 2 +#define ABORT 1 +#define STAGE 0 -DigitalIn press(USER_BUTTON); +//Action group statuses +#define AGSAS 0 +#define AGRCS 1 +#define AGLight 2 +#define AGGear 3 +#define AGBrakes 4 +#define AGAbort 5 +#define AGCustom01 6 +#define AGCustom02 7 +#define AGCustom03 8 +#define AGCustom04 9 +#define AGCustom05 10 +#define AGCustom06 11 +#define AGCustom07 12 +#define AGCustom08 13 +#define AGCustom09 14 +#define AGCustom10 15 + +//SAS Modes +#define SMOFF 0 +#define SMSAS 1 +#define SMPrograde 2 +#define SMRetroGrade 3 +#define SMNormal 4 +#define SMAntinormal 5 +#define SMRadialIn 6 +#define SMRadialOut 7 +#define SMTarget 8 +#define SMAntiTarget 9 +#define SMManeuverNode 10 + +//Navball Target Modes +#define NAVBallIGNORE 0 +#define NAVBallORBIT 1 +#define NAVBallSURFACE 2 +#define NAVBallTARGET 3 + +//macro +#define details(name) (uint8_t*)&name,sizeof(name) + +//if no message received from KSP for more than 2s, go idle +#define IDLETIMER 8000 +#define CONTROLREFRESH 25 + +//warnings +#define GWARN 9 //9G Warning +#define GCAUTION 5 //5G Caution +#define FUELCAUTION 10.0 //10% Fuel Caution +#define FUELWARN 5.0 //5% Fuel warning - char id; //1 - float AP; //2 - float PE; //3 - float SemiMajorAxis; //4 - float SemiMinorAxis; //5 - float VVI; //6 - float e; //7 - float inc; //8 - float G; //9 - int TAp; //10 - int TPe; //11 - float TrueAnomaly; //12 - float Density; //13 - int period; //14 - float RAlt; //15 - float Alt; //16 - float Vsurf; //17 - float Lat; //18 - float Lon; //19 - float LiquidFuelTot; //20 - float LiquidFuel; //21 - float OxidizerTot; //22 - float Oxidizer; //23 - float EChargeTot; //24 - float ECharge; //25 - float MonoPropTot; //26 - float MonoProp; //27 - float IntakeAirTot; //28 - float IntakeAir; //29 - float SolidFuelTot; //30 - float SolidFuel; //31 - float XenonGasTot; //32 - float XenonGas; //33 - float LiquidFuelTotS; //34 - float LiquidFuelS; //35 - float OxidizerTotS; //36 - float OxidizerS; //37 - uint32_t MissionTime; //38 - float deltaTime; //39 - float VOrbit; //40 - uint32_t MNTime; //41 - float MNDeltaV; //42 - uint16_t Pitch; //43 - uint16_t Roll; //44 - uint16_t Heading; //45 - uint16_t ActionGroups; //46 status bit order:SAS, RCS, Light, Gear, Brakes, Abort, Custom01 - 10 - char SOINumber; //47 SOI Number (decimal format: sun-planet-moon e.g. 130 = kerbin, 131 = mun) - char MaxOverHeat; //48 Max part overheat (% percent) - float MachNumber; //49 - float IAS; //50 Indicated Air Speed - char CurrentStage; //51 Current stage number - char TotalStage; //52 TotalNumber of stages - float TargetDist; //53 Distance to targeted vessel (m) - float TargetV; //54 Target vessel relative velocity (m/s) - char NavballSASMode; //55 Combined byte for navball target mode and SAS mode - // First four bits indicate AutoPilot mode: - // 0 SAS is off //1 = Regular Stability Assist //2 = Prograde - // 3 = RetroGrade //4 = Normal //5 = Antinormal //6 = Radial In - // 7 = Radial Out //8 = Target //9 = Anti-Target //10 = Maneuver node - // Last 4 bits set navball mode. (0=ignore,1=ORBIT,2=SURFACE,3=TARGET) - uint16_t ProgradePitch; //56 Pitch Of the Prograde Vector; int_16 ranging from (-0x8000(-360 degrees) to 0x7FFF(359.99ish degrees)); - uint16_t ProgradeHeading;//57 Heading Of the Prograde Vector; see above for range (Prograde vector depends on navball mode, eg Surface/Orbit/Target) - uint16_t ManeuverPitch; //58 Pitch Of the Maneuver Vector; see above for range; (0 if no Maneuver node) - uint16_t ManeuverHeading;//59 Heading Of the Maneuver Vector; see above for range; (0 if no Maneuver node) - uint16_t TargetPitch; //60 Pitch Of the Target Vector; see above for range; (0 if no Target) - uint16_t TargetHeading; //61 Heading Of the Target Vector; see above for range; (0 if no Target) - uint16_t NormalHeading; //62 Heading Of the Prograde Vector; see above for range; (Pitch of the Heading Vector is always 0) - char vesselSync; //63 Starting with 1, increased on every VesselChange +void Indicators(); +void initLEDS(); +void LEDSAllOff(); +void InitTxPackets(); +int input(); +char ControlStatus(char n); +void output(); +void controls(); +void controlsInit(); +char getSASMode(); +char getNavballMode(); +void setSASMode(char m); +void setNavballMode(char m); +void MainControls(char n, bool s); +void ControlGroups(char n, bool s); +bool KSPBoardReceiveData(); +void KSPBoardSendData(uint8_t * data, uint8_t len); +void Handshake(); + +DigitalIn ControlButton(USER_BUTTON); + +int deadtime, deadtimeOld, controlTime, controlTimeOld; +int now; +Timer t; +bool Connected = false; +char VesselID = 0; +char caution = 0, warning = 0, id; + +uint8_t rx_len; +uint16_t * address; +char buffer[256]; //address for temporary storage and parsing buffer +uint8_t structSize; +uint8_t rx_array_inx; //index for RX parsing buffer +uint8_t calc_CS; //calculated Chacksum +char payloadBuffer[255]; -void float2Bytes(char bytes_temp[4],float float_variable){ - union { - float a; - unsigned char bytes[4]; - } thing; - thing.a = float_variable; - memcpy(bytes_temp, thing.bytes, 4); -} - -void unpackVesselData(char *PayloadBuffer, int payloadLength) +struct VesselData { - char varBuffer[8]; - id = PayloadBuffer[0]; //1 - if(id == 0x01) - { - //float AP - 1 - for(int i=0; i < 4; i++) - { - varBuffer[i]=PayloadBuffer[i+1]; - } - /** - varBuffer[1]=PayloadBuffer[2]; - varBuffer[2]=PayloadBuffer[3]; - varBuffer[3]=PayloadBuffer[4]; - **/ - AP = *(float *)&varBuffer; - - // float PE - 5 - for(int i=0; i < 4; i++) - { - varBuffer[i]=PayloadBuffer[i+5]; - } - PE = *(float *)&varBuffer; - - //float SemiMajorAxis - 9 - for(int i=0; i < 4; i++) - { - varBuffer[i]=PayloadBuffer[i+9]; - } - SemiMajorAxis = *(float *)&varBuffer; - - //float SemiMinorAxis - 13 - for(int i=0; i < 4; i++) - { - varBuffer[i]=PayloadBuffer[i+13]; - } - SemiMinorAxis = *(float *)&varBuffer; //5 - - //float VVI 17 - for(int i=0; i < 4; i++) - { - varBuffer[i]=PayloadBuffer[i+17]; - } - VVI = *(float *)&varBuffer; //6 - - //float e - 21 - for(int i=0; i < 4; i++) - { - varBuffer[i]=PayloadBuffer[i+21]; - } - e = *(float *)&varBuffer; //7 - - //float inc - 25 - for(int i=0; i < 4; i++) - { - varBuffer[i]=PayloadBuffer[i+25]; - } - inc = *(float *)&varBuffer; //8 - } - else - { - printf("Bad Packet Id: %d", id); - } -} + char id; //1 + float AP; //2 + float PE; //3 + float SemiMajorAxis; //4 + float SemiMinorAxis; //5 + float VVI; //6 + float e; //7 + float inc; //8 + float G; //9 + int TAp; //10 + int TPe; //11 41 + float TrueAnomaly; //12 + float Density; //13 + int period; //14 + float RAlt; //15 + float Alt; //16 61 + float Vsurf; //17 + float Lat; //18 + float Lon; //19 + float LiquidFuelTot; //20 + float LiquidFuel; //21 + float OxidizerTot; //22 + float Oxidizer; //23 + float EChargeTot; //24 + float ECharge; //25 + float MonoPropTot; //26 + float MonoProp; //27 + float IntakeAirTot; //28 + float IntakeAir; //29 + float SolidFuelTot; //30 + float SolidFuel; //31 + float XenonGasTot; //32 + float XenonGas; //33 + float LiquidFuelTotS; //34 + float LiquidFuelS; //35 + float OxidizerTotS; //36 + float OxidizerS; //37 + uint32_t MissionTime; //38 + float deltaTime; //39 + float VOrbit; //40 + uint32_t MNTime; //41 + float MNDeltaV; //42 165 + uint16_t Pitch; //43 + uint16_t Roll; //44 + uint16_t Heading; //45 + uint16_t ActionGroups; //46 173 status bit order:SAS, RCS, Light, Gear, Brakes, Abort, Custom01 - 10 + char SOINumber; //47 SOI Number (decimal format: sun-planet-moon e.g. 130 = kerbin, 131 = mun) + char MaxOverHeat; //48 175 Max part overheat (% percent) + float MachNumber; //49 + float IAS; //50 Indicated Air Speed + char CurrentStage; //51 Current stage number + char TotalStage; //52 185 TotalNumber of stages + float TargetDist; //53 Distance to targeted vessel (m) + float TargetV; //54 193 Target vessel relative velocity (m/s) + char NavballSASMode; //55 194 Combined char for navball target mode and SAS mode + // First four bits indicate AutoPilot mode: + // 0 SAS is off //1 = Regular Stability Assist //2 = Prograde + // 3 = RetroGrade //4 = Normal //5 = Antinormal //6 = Radial In + // 7 = Radial Out //8 = Target //9 = Anti-Target //10 = Maneuver node + // Last 4 bits set navball mode. (0=ignore,1=ORBIT,2=SURFACE,3=TARGET) + uint16_t ProgradePitch; //56 Pitch Of the Prograde Vector; int_16 ranging from (-0x8000(-360 degrees) to 0x7FFF(359.99ish degrees)); + uint16_t ProgradeHeading;//57 Heading Of the Prograde Vector; see above for range (Prograde vector depends on navball mode, eg Surface/Orbit/Target) + uint16_t ManeuverPitch; //58 Pitch Of the Maneuver Vector; see above for range; (0 if no Maneuver node) + uint16_t ManeuverHeading;//59 Heading Of the Maneuver Vector; see above for range; (0 if no Maneuver node) + uint16_t TargetPitch; //60 Pitch Of the Target Vector; see above for range; (0 if no Target) + uint16_t TargetHeading; //61 Heading Of the Target Vector; see above for range; (0 if no Target) + uint16_t NormalHeading; //62 Heading Of the Prograde Vector; see above for range; (Pitch of the Heading Vector is always 0) + char vesselSync; //63 208 Starting with 1, increased on every VesselChange +}; +struct HandShakePacket +{ + char id; + char M1; + char M2; + char M3; +}; +struct ControlPacket { + char id; + char MainControls; //SAS RCS Lights Gear Brakes Precision Abort Stage + char Mode; //0 = stage, 1 = docking, 2 = map + short ControlGroup; //control groups 1-10 in 2 chars + char NavballSASMode; //AutoPilot mode + char AdditionalControlByte1; //9 + int32_t Pitch; //-1000 -> 1000 + int32_t Roll; //-1000 -> 1000 + int32_t Yaw; //-1000 -> 1000 + int32_t TX; //-1000 -> 1000 + int32_t TY; //-1000 -> 1000 + int32_t TZ; //-1000 -> 1000 + int32_t WheelSteer; //-1000 -> 1000 + int32_t Throttle; // 0 -> 1000 + int32_t WheelThrottle; // 0 -> 1000 + char vesselSync; //Starting with 1, increased on every VesselChange +}; + +HandShakePacket HPacket; +VesselData VData; +ControlPacket CPacket; +EthernetInterface eth; +TCPSocketConnection sock; + int main() { - - EthernetInterface eth; + //SETUP + + t.start(); + printf("\n\r KSP mbedIO V0.1 \n\r"); eth.init(); //Use DHCP eth.connect(); printf("\nServer IP Address is %s\n\r", eth.getIPAddress()); @@ -193,228 +248,710 @@ Endpoint KSPServer; char buffer[256]; - printf("Waiting for UDP packet...\n\r"); - int n = server.receiveFrom(KSPServer, buffer, sizeof(buffer)); - buffer[n] = '\0'; - #if DEBUG - printf("Received packet from: %s\n\r", KSPServer.get_address()); - //printf("Packet contents : '%s'\n\r",buffer); - #endif - // server.sendTo(client, buffer, n) - - - /** - - HSPacket.id=0; - HSPacket.M1=3; - HSPacket.M2=1; - HSPacket.status=4; - **/ - char HSPayload[4]={0x00, 0x03, 0x01, 0x04}; - char HSPacket[sizeof(HSPayload)+4]; - char Header1 = 0xBE; - char Header2 = 0xEF; - int checksum = sizeof(HSPayload); - - HSPacket[0] = Header1; - HSPacket[1] = Header2; - HSPacket[2] = sizeof(HSPayload); - - int CurrentPacketLength=0; - int CurrentBytesRead=0; - char PayloadBuffer[300]; - char NewPacketBuffer[300]; + printf("Waiting for UDP packet...\n\r"); + int n = server.receiveFrom(KSPServer, buffer, sizeof(buffer)); + buffer[n] = '\0'; + #if DEBUG + printf("Received packet from: %s\n\r", KSPServer.get_address()); + #endif - for (int i = 0; i < sizeof(HSPayload); i++) - { - checksum ^= HSPayload[i]; - HSPacket[i+3] = HSPayload[i]; - } - HSPacket[sizeof(HSPacket)-1] = checksum; - - - for(int i=0;i<sizeof(HSPacket);i++) - { - printf("%c", HSPacket[i]); - } - - //makePacket(HSPayload, HSPacket); - - TCPSocketConnection sock; + sock.set_blocking(false, 500); // Set socket to non-blocking and set the timeout for 500ms while (sock.connect(KSPServer.get_address(), PORT) < 0) { printf("Unable to connect to KSPServer on Port %d \r\n", PORT); wait(1); } + printf("Connected to KSPServer on Port %d \r\n", PORT); + Handshake(); + printf("Handshake sent \r\n"); - printf("Connected to KSP Server \n\r"); - sock.send(HSPacket, sizeof(HSPacket)); + + initLEDS(); + InitTxPackets(); + // controlsInit(); + + LEDSAllOff(); + while(true) + { + input(); + output(); + } +} + + + +////////////////////////////////////////////////// +/////////////////// CONTROLS ///////////////////// +////////////////////////////////////////////////// + +void Indicators() { + caution = 0; + warning = 0; + + caution += VData.G > GCAUTION; + warning += VData.G > GWARN; + caution += VData.LiquidFuelS/VData.LiquidFuelTotS*100 < FUELCAUTION; + warning += VData.LiquidFuelS/VData.LiquidFuelTotS*100 < FUELWARN; + + if (caution != 0) + { + printf("Yellow! \n\r"); + } + else + { + //yel off + } - while (sock.is_connected()) { - char buffer[300]; - int ret; + if (warning != 0) + { + printf("RED! \n\r"); + } + else + { + //red off + } + #if OUTPUTENABLE + printf("AP : %f \n\r", VData.AP); + printf("Sync : %d \n\r", VData.vesselSync); + printf("Alt : %f \n\r", VData.Alt); + printf("Vsurf : %f \n\r", VData.Vsurf); + if(ControlStatus(AGSAS)) printf("AGSAS ON \n\r"); + if(ControlStatus(AGRCS)) printf("AGRCS ON \n\r"); + if(ControlStatus(AGCustom01)) printf("AGCustom1 ON \n\r"); + #endif +} + +void initLEDS() { + +} + +void LEDSAllOff() { + +} + +void InitTxPackets() { + HPacket.id = 0; + CPacket.id = 101; +} + + +////////////////////////////////////////////////// +//////////////////// INPUT ///////////////////// +////////////////////////////////////////////////// + +int input() { + int returnValue = -1; + now = t.read_ms(); + + if (KSPBoardReceiveData()) + { + deadtimeOld = now; + returnValue = id; + switch(id) + { + case 0: //Handshake packet + Handshake(); + #if DEBUG + printf("HS Packet recieved\n\r"); + #endif + break; + case 1: + VesselID = VData.vesselSync; + Indicators(); + #if DEBUG + printf("VD Packet recieved\n\r"); + #endif + break; + } + Connected = true; + } + + else + { //if no message received for a while, go idle + deadtime = now - deadtimeOld; + if (deadtime > IDLETIMER) + { + deadtimeOld = now; + Connected = false; + LEDSAllOff(); + printf("No packets for a while... going Idle \n\r"); + } + } + + return returnValue; +} + +char ControlStatus(char n) +{ + return ((VData.ActionGroups >> n) & 1) == 1; +} + +////////////////////////////////////////////////// +///////////////////// OUTPUT ///////////////////// +////////////////////////////////////////////////// + +void output() { + now = t.read_ms(); + controlTime = now - controlTimeOld; + if (controlTime > CONTROLREFRESH) { + controlTimeOld = now; + controls(); + } +} + +void controls() { + if (Connected) { + + if (!ControlButton) { //--------- This is how you do main controls + MainControls(SAS, 1); + setSASMode(SMSAS); //setting SAS mode + #if DEBUG + printf("SAS PRESS \n\r"); + #endif + //setNavballMode(NAVBallSURFACE); //setting navball mode + } + else { + //setNavballMode(NAVBallTARGET); + MainControls(SAS, 0); + } + + if (ControlButton) + MainControls(RCS, 1); + else + MainControls(RCS, 0); + + /** + if (digitalRead(CG1PIN)) //--------- This is how you do control groups + ControlGroups(1, 1); + else + ControlGroups(1, 0); + **/ + /* + if (getSASMode() == SMPrograde) { //--------- This is how you read SAS modes + //Blink LED, do stuff, etc. + } + + if (getNavballMode() == NAVBallTARGET) { //--------- This is how you read navball modes + //Blink LED, do stuff, etc. + } + */ + + //This is an example of reading analog inputs to an axis, with deadband and limits + //CPacket.Throttle = constrain(map(analogRead(THROTTLEPIN), THROTTLEDB, 1024 - THROTTLEDB, 0, 1000), 0, 1000); + + //This is an example of reading analog inputs to an axis, with deadband and limits + //CPacket.Pitch = constrain(map(analogRead(THROTTLEPIN),0,1024,-1000,1000),-1000, 1000); + CPacket.vesselSync = VData.vesselSync; + KSPBoardSendData(details(CPacket)); + } +} + +void controlsInit() { + /** + pinMode(SASPIN, INPUT_PULLUP); + pinMode(RCSPIN, INPUT_PULLUP); + pinMode(CG1PIN, INPUT_PULLUP); + **/ +} + +char getSASMode() { + return VData.NavballSASMode & 0b00001111; // leaves alone the lower 4 bits of; all higher bits set to 0. +} + +char getNavballMode() { + return VData.NavballSASMode >> 4; // leaves alone the higher 4 bits of; all lower bits set to 0. +} + +void setSASMode(char m) { + CPacket.NavballSASMode &= 0b11110000; + CPacket.NavballSASMode += m; +} + +void setNavballMode(char m) { + CPacket.NavballSASMode &= 0b00001111; + CPacket.NavballSASMode += m << 4; +} + +void MainControls(char n, bool s) { + if (s) + CPacket.MainControls |= (1 << n); // forces nth bit of x to be 1. all other bits left alone. + else + CPacket.MainControls &= ~(1 << n); // forces nth bit of x to be 0. all other bits left alone. +} + +void ControlGroups(char n, bool s) { + if (s) + CPacket.ControlGroup |= (1 << n); // forces nth bit of x to be 1. all other bits left alone. + else + CPacket.ControlGroup &= ~(1 << n); // forces nth bit of x to be 0. all other bits left alone. +} + + + + +////////////////////////////////////////////////// +//////////////// COMMUNICATIONS/////////////////// +////////////////////////////////////////////////// + + + +bool KSPBoardReceiveData() { + int ret; - ret = sock.receive(buffer, sizeof(buffer)-1); - buffer[ret] = '\0'; - if(ret > 0) + ret = sock.receive(buffer, sizeof(buffer)-1); + + if(ret > 0) + { + int packetCheckState = 0; + #if DEBUG + printf("Packet Rx'd \n\r"); + #endif + for(int x = 0; x < 4; x++) { - int CurrentState = 0; - - for (int x = 0; x < sizeof(buffer)-1; x++) - { - switch (CurrentState) + switch(packetCheckState){ + case 0: // CHECK HEADER 1 + if(buffer[packetCheckState] == 0xBE) { - case 0: //HEADER 1 - if (buffer[x] == 0xBE) CurrentState = 1; - break; - case 1: - if (buffer[x] == 0xEF) CurrentState = 2; - else CurrentState = 0; - break; - case 2: //HEADER 2 - CurrentPacketLength = (int)buffer[x]; - checksum = CurrentPacketLength; - CurrentBytesRead = 0; - CurrentState = 3; - break; - case 3: //PAYLOAD SIZE - PayloadBuffer[CurrentBytesRead] = buffer[x]; - CurrentBytesRead++; - if (CurrentBytesRead == CurrentPacketLength) - { - CurrentState = 4; - } - break; - case 4://CHECKSUM - for (int i = 0; i < CurrentPacketLength; i++) - { - checksum ^= PayloadBuffer[i]; - } - if(buffer[x] == checksum) - { - #if DEBUG - printf("Checksum Success. Payload recieved. \r\n"); - #endif - } - else printf("Checksum Failed! Sorry. \r\n"); - CurrentState = 0; - break; + packetCheckState++; + } + break; + case 1: // CHECK HEADER 2 + if(buffer[packetCheckState] == 0xEF) + { + packetCheckState++; } - } - #if DEBUG - printf("Payload ID: %d \r\n", PayloadBuffer[0]); - #endif - if(PayloadBuffer[0] == 0) - { - + break; + case 2: // GET PAYLOAD SIZE + rx_len = buffer[packetCheckState]; + packetCheckState++; + #if DEBUG + printf("PL Size at Rx: %d \n\r", rx_len); + #endif + break; + case 3: + id = buffer[packetCheckState]; + #if DEBUG + printf("Packet ID: %d \n\r", id); + #endif + if(id == 0) + { + structSize = sizeof(HPacket); + address = (uint16_t*)&HPacket; + } + else if(id == 1) + { + structSize = sizeof(VData); + address = (uint16_t*)&VData; + } + else + { + printf("Bad Packet ID: %d", buffer[packetCheckState]); + packetCheckState = 0; + } + break; + default : + printf("Something went wrong in Packet Rx Loop \r\n"); + break; } - if(PayloadBuffer[0] == 1) + } + + if(packetCheckState == 3) //We had a valid packet + { + calc_CS = rx_len; + for(int i = 0; i < rx_len; i++) { - unpackVesselData(PayloadBuffer, CurrentPacketLength); - #if OUTPUTENABLE - printf("AP %f \n\r", AP); - #endif - printf("00000%s",PayloadBuffer); - printf("CCCCC%c",checksum); - //sock.send(HSPacket, sizeof(HSPacket)); + payloadBuffer[i] = buffer[i+3]; + calc_CS^=buffer[i+3]; } - else + if(calc_CS == buffer[rx_len+3]) //CS Check { + char varBuffer[4]; + #if DEBUG + printf("Checksum Passed! \n\r"); + #endif + + // A note to the reader, I hate this as much as you do. I really do. + // But I'm a shitty programmer and this compiler pads structs for alignment and it fucks up the memcpy approach. + // I fought this, I really did. But it's 2AM, and I just want my fucking code to work. So forgive me this sin. + + //memcpy(address,payloadBuffer,structSize); - } - - //55 Combined byte for navball target mode and SAS mode + VData.id = payloadBuffer[0]; //1 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+1]; + } + VData.AP = *(float *)&varBuffer; + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+5]; + } + VData.PE = *(float *)&varBuffer; //3 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+9]; + } + VData.SemiMajorAxis = *(float *)&varBuffer; //4 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+13]; + } + VData.SemiMinorAxis = *(float *)&varBuffer; //5 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+17]; + } + VData.VVI = *(float *)&varBuffer; //6 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+21]; + } + VData.e = *(float *)&varBuffer; //7 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+25]; + } + VData.inc = *(float *)&varBuffer; //8 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+29]; + } + VData.G = *(float *)&varBuffer; //9 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+33]; + } + VData.TAp = *(int *)&varBuffer; //10 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+37]; + } + VData.TPe = *(int *)&varBuffer; //11 41 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+41]; + } + VData.TrueAnomaly = *(float *)&varBuffer; //12 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+44]; + } + VData.Density = *(float *)&varBuffer; //13 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+49]; + } + VData.period = *(int *)&varBuffer; //14 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+53]; + } + VData.RAlt = *(float *)&varBuffer; //15 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+57]; + } + VData.Alt = *(float *)&varBuffer; //16 61 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+61]; + } + VData.Vsurf = *(float *)&varBuffer; //17 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+65]; + } + VData.Lat = *(float *)&varBuffer; //18 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+69]; + } + VData.Lon = *(float *)&varBuffer; //19 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+73]; + } + VData.LiquidFuelTot = *(float *)&varBuffer; //20 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+77]; + } + VData.LiquidFuel = *(float *)&varBuffer; //21 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+81]; + } + VData.OxidizerTot = *(float *)&varBuffer; //22 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+85]; + } + VData.Oxidizer = *(float *)&varBuffer; //23 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+89]; + } + VData.EChargeTot = *(float *)&varBuffer; //24 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+93]; + } + VData.ECharge = *(float *)&varBuffer; //25 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+97]; + } + VData.MonoPropTot = *(float *)&varBuffer; //26 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+101]; + } + VData.MonoProp = *(float *)&varBuffer; //27 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+104]; + } + VData.IntakeAirTot = *(float *)&varBuffer; //28 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+109]; + } + VData.IntakeAir = *(float *)&varBuffer; //29 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+113]; + } + VData.SolidFuelTot = *(float *)&varBuffer; //30 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+117]; + } + VData.SolidFuel = *(float *)&varBuffer; //31 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+121]; + } + VData.XenonGasTot = *(float *)&varBuffer; //32 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+125]; + } + VData.XenonGas = *(float *)&varBuffer; //33 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+129]; + } + VData.LiquidFuelTotS = *(float *)&varBuffer; //34 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+133]; + } + VData.LiquidFuelS = *(float *)&varBuffer; //35 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+137]; + } + VData.OxidizerTotS = *(float *)&varBuffer; //36 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+141]; + } + VData.OxidizerS = *(float *)&varBuffer; //37 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+145]; + } + VData.MissionTime = *(uint32_t *)&varBuffer; //38 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+149]; + } + VData.deltaTime = *(float *)&varBuffer; //39 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+153]; + } + VData.VOrbit = *(float *)&varBuffer; //40 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+157]; + } + VData.MNTime = *(uint32_t *)&varBuffer; //41 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+161]; + } + VData.MNDeltaV = *(float *)&varBuffer; //42 165 + for(int i=0; i < 2; i++) + { + varBuffer[i]=payloadBuffer[i+165]; + } + VData.Pitch = *(float *)&varBuffer; //43////////////////////////// + for(int i=0; i < 2; i++) + { + varBuffer[i]=payloadBuffer[i+167]; + } + VData.Roll = *(float *)&varBuffer; //44 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+169]; + } + VData.Heading = *(float *)&varBuffer; //45 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+173]; + } + VData.ActionGroups = *(float *)&varBuffer; //46 173 status bit order:SAS, RCS, Light, Gear, Brakes, Abort, Custom01 - 10 + VData.SOINumber = payloadBuffer[177]; //47 SOI Number (decimal format: sun-planet-moon e.g. 130 = kerbin, 131 = mun) + VData.MaxOverHeat = payloadBuffer[178]; //48 175 Max part overheat (% percent) + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+179]; + } + VData.MachNumber = *(float *)&varBuffer; //49 + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+183]; + } + VData.IAS = *(float *)&varBuffer; //50 Indicated Air Speed + + VData.CurrentStage = payloadBuffer[187]; //51 Current stage number + VData.TotalStage = payloadBuffer[188]; //52 185 TotalNumber of stages + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+189]; + } + VData.TargetDist = *(float *)&varBuffer; //53 Distance to targeted vessel (m) + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+193]; + } + VData.TargetV = *(float *)&varBuffer; //54 193 Target vessel relative velocity (m/s) + VData.NavballSASMode = payloadBuffer[197]; //55 194 Combined char for navball target mode and SAS mode // First four bits indicate AutoPilot mode: // 0 SAS is off //1 = Regular Stability Assist //2 = Prograde // 3 = RetroGrade //4 = Normal //5 = Antinormal //6 = Radial In // 7 = Radial Out //8 = Target //9 = Anti-Target //10 = Maneuver node // Last 4 bits set navball mode. (0=ignore,1=ORBIT,2=SURFACE,3=TARGET) - char MainControls = 0b11111111; //SAS RCS Lights Gear Brakes Precision Abort Stage - char Mode = 0b00000000; //0 = stage, 1 = docking, 2 = map (Bit 0-3) - //0 = Auto, 1 = Free, 2 = Orbital, 3 = Chase, 4 = Locked (Bit 4-7) - uint16_t ControlGroup = 0b00000000; //control groups 1-10 in 2 bytes - char NavballSASMode = press; //AutoPilot mode (See above for AutoPilot modes)(Ignored if the equal to zero or out of bounds (>10)) //Navball mode - short Throttle = 500; - if(press) - { - NavballSASMode = 0b01000000; - Throttle = 0; - printf("PRESS\n\r\n"); + for(int i=0; i < 2; i++) + { + varBuffer[i]=payloadBuffer[i+198]; + } + VData.ProgradePitch = *(float *)&varBuffer; //56 Pitch Of the Prograde Vector; int_16 ranging from (-0x8000(-360 degrees) to 0x7FFF(359.99ish degrees)); + for(int i=0; i < 2; i++) + { + varBuffer[i]=payloadBuffer[i+200]; + } + VData.ProgradeHeading = *(float *)&varBuffer;//57 Heading Of the Prograde Vector; see above for range (Prograde vector depends on navball mode, eg Surface/Orbit/Target) + for(int i=0; i < 2; i++) + { + varBuffer[i]=payloadBuffer[i+202]; + } + VData.ManeuverPitch = *(float *)&varBuffer; //58 Pitch Of the Maneuver Vector; see above for range; (0 if no Maneuver node) + for(int i=0; i < 4; i++) + { + varBuffer[i]=payloadBuffer[i+204]; + } + VData.ManeuverHeading = *(float *)&varBuffer;//59 Heading Of the Maneuver Vector; see above for range; (0 if no Maneuver node) + for(int i=0; i < 2; i++) + { + varBuffer[i]=payloadBuffer[i+205]; + } + VData.TargetPitch = *(float *)&varBuffer; //60 Pitch Of the Target Vector; see above for range; (0 if no Target) + for(int i=0; i < 2; i++) + { + varBuffer[i]=payloadBuffer[i+206]; + } + VData.TargetHeading = *(float *)&varBuffer; //61 Heading Of the Target Vector; see above for range; (0 if no Target) + for(int i=0; i < 2; i++) + { + varBuffer[i]=payloadBuffer[i+207]; + } + VData.NormalHeading = *(float *)&varBuffer; //62 Heading Of the Prograde Vector; see above for range; (Pitch of the Heading Vector is always 0) + VData.vesselSync = payloadBuffer[208]; + + rx_len = 0; + return true; } else { - NavballSASMode = 0b00000000; + //failed checksum, need to clear this out anyway + printf("Failed Checksum! Sorry \n\r"); + rx_len = 0; + rx_array_inx = 1; + return false; } - - - char AdditionalControlByte1 = 0; //Bit 0: Open Menu, Bit 1: Open Map - short Pitch = 0; //-1000 -> 1000 - short Roll = 0; //-1000 -> 1000 - short Yaw = 0; //-1000 -> 1000 - short TX = 0; //-1000 -> 1000 - short TY = 0; //-1000 -> 1000 - short TZ = 0; //-1000 -> 1000 - short WheelSteer = 0; //-1000 -> 1000 - //short Throttle = 500; // 0 -> 1000 - short WheelThrottle = 0; // 0 -> 1000 - char vesselSync = PayloadBuffer[sizeof(PayloadBuffer)-1]; - char vSync = vesselSync + 30; - printf("Vsync %c \n\r\n", vSync); - char CSPayload[26]; - char CSPacket[sizeof(CSPayload)+4]; - Header1 = 0xBE; - Header2 = 0xEF; - checksum = sizeof(CSPayload); - - CSPacket[0] = Header1; - CSPacket[1] = Header2; - CSPacket[2] = sizeof(CSPayload); - - CSPayload[0] = 101; //Csid 101 - CSPayload[1] = MainControls; - CSPayload[2] = Mode; - CSPayload[3] = ControlGroup & 0xff; - CSPayload[4] = (ControlGroup >> 8); - CSPayload[5] = NavballSASMode; - CSPayload[6] = AdditionalControlByte1; - CSPayload[7] = Pitch & 0xff; - CSPayload[8] = (Pitch >> 8); - CSPayload[9] = Roll & 0xff; - CSPayload[10] = (Roll >> 8); - CSPayload[11] = Yaw & 0xff; - CSPayload[12] = (Yaw >> 8); - CSPayload[13] = TX & 0xff; - CSPayload[14] = (TX >> 8); - CSPayload[15] = TY & 0xff; - CSPayload[16] = (TY >> 8); - CSPayload[17] = TZ & 0xff; - CSPayload[18] = (TZ >> 8); - CSPayload[19] = WheelSteer & 0xff; - CSPayload[20] = (WheelSteer >> 8); - CSPayload[21] = Throttle & 0xff; - CSPayload[22] = (Throttle >> 8); - CSPayload[23] = WheelThrottle & 0xff; - CSPayload[24] = (WheelThrottle >> 8); - CSPayload[25] = vesselSync; - - for (int i = 0; i < sizeof(CSPayload); i++) - { - checksum ^= CSPayload[i]; - CSPacket[i+3] = CSPayload[i]; - } - CSPacket[sizeof(CSPacket)-1] = checksum; - sock.send_all(CSPacket, sizeof(CSPacket)); - - + + } -// sock.send_all(HSPacket, sizeof(HSPacket)); } - printf("We got shut down! Socket Closed!"); - sock.close(); + return false; +} + +void KSPBoardSendData(uint8_t * data, uint8_t len){ + uint8_t CS = len; + char fullPacket[len+4]; + fullPacket[0] = 0xBE; + fullPacket[1] = 0xEF; + fullPacket[2] = len; - eth.disconnect(); + if(*(data) == 101) + { + fullPacket[3] = 101; //Csid 101 + fullPacket[4] = CPacket.MainControls; + fullPacket[5] = CPacket.Mode; + fullPacket[6] = CPacket.ControlGroup & 0xff; + fullPacket[7] = (CPacket.ControlGroup >> 8); + fullPacket[8] = CPacket.NavballSASMode; + fullPacket[9] = CPacket.AdditionalControlByte1; + fullPacket[10] = CPacket.Pitch & 0xff; + fullPacket[11] = (CPacket.Pitch >> 8); + fullPacket[12] = CPacket.Roll & 0xff; + fullPacket[13] = (CPacket.Roll >> 8); + fullPacket[14] = CPacket.Yaw & 0xff; + fullPacket[15] = (CPacket.Yaw >> 8); + fullPacket[16] = CPacket.TX & 0xff; + fullPacket[17] = (CPacket.TX >> 8); + fullPacket[18] = CPacket.TY & 0xff; + fullPacket[19] = (CPacket.TY >> 8); + fullPacket[20] = CPacket.TZ & 0xff; + fullPacket[21] = (CPacket.TZ >> 8); + fullPacket[22] = CPacket.WheelSteer & 0xff; + fullPacket[23] = (CPacket.WheelSteer >> 8); + fullPacket[24] = CPacket.Throttle & 0xff; + fullPacket[25] = (CPacket.Throttle >> 8); + fullPacket[26] = CPacket.WheelThrottle & 0xff; + fullPacket[27] = (CPacket.WheelThrottle >> 8); + fullPacket[28] = CPacket.vesselSync; + for(int i = 0; i<len; i++) + { + CS^= fullPacket[i+3]; + } + fullPacket[sizeof(fullPacket)-1] = CS; + } + else + { + for(int i = 0; i<len; i++) + { + CS^=*(data+i); + fullPacket[i+3] = *(data+i); + } + fullPacket[sizeof(fullPacket)-1] = CS; + } + #if DEBUG + printf("Sending a Packet \n\r"); + #endif + sock.send(fullPacket, sizeof(fullPacket)); // Send the packet +} + +void Handshake(){ + + HPacket.id = 0; + HPacket.M1 = 3; + HPacket.M2 = 1; + HPacket.M3 = 4; - while(1) {} -} \ No newline at end of file + KSPBoardSendData(details(HPacket)); +}