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:
- 17:00d66e5edf58
- Parent:
- 16:0eda62f0d9e8
--- a/main.cpp Sun Mar 15 04:35:51 2020 +0000 +++ b/main.cpp Tue Mar 17 01:25:35 2020 +0000 @@ -8,7 +8,7 @@ #define PORT 2342 #define DEBUG 0 -#define OUTPUTENABLE 0 +#define OUTPUTENABLE 1 #if DEBUG @@ -126,6 +126,8 @@ uint8_t calc_CS; //calculated Chacksum char payloadBuffer[255]; +#pragma pack (1) + struct VesselData { char id; //1 @@ -231,50 +233,65 @@ ControlPacket CPacket; EthernetInterface eth; TCPSocketConnection sock; - +UDPSocket server; int main() { //SETUP + char buffer[256]; + int ConnectionState = 0; 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()); - - UDPSocket server; - server.bind(PORT); - 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()); - #endif - - 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"); - - - initLEDS(); - InitTxPackets(); - // controlsInit(); - - LEDSAllOff(); while(true) { - input(); - output(); + switch(ConnectionState) + { + case 0:// Connect to UDP server and get server IP address + { + server.bind(PORT); + printf("Waiting for UDP packet...\n\r"); + while(server.receiveFrom(KSPServer, buffer, sizeof(buffer)) < 0) + { + //Waiting for UDP to Connect + } + #if DEBUG + printf("Received packet from: %s\n\r", KSPServer.get_address()); + #endif + ConnectionState++; + break; + } + case 1: // Connect to TCP Server + { + sock.set_blocking(false, 1500); // Set socket to non-blocking timeout to 1.5s + 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"); + ConnectionState++; + break; + } + case 2: // We're Connected, check connection and keep running + { + initLEDS(); + InitTxPackets(); + while(sock.is_connected()) + { + input(); + output(); + } + sock.close(); + printf("Connection Lost, Reconnecting... \n\r"); + ConnectionState = 0; + break; + } + } } } @@ -290,8 +307,8 @@ caution += VData.G > GCAUTION; warning += VData.G > GWARN; - caution += VData.LiquidFuelS/VData.LiquidFuelTotS*100 < FUELCAUTION; - warning += VData.LiquidFuelS/VData.LiquidFuelTotS*100 < FUELWARN; + // caution += VData.LiquidFuelS/VData.LiquidFuelTotS*100 < FUELCAUTION; + // warning += VData.LiquidFuelS/VData.LiquidFuelTotS*100 < FUELWARN; if (caution != 0) { @@ -311,13 +328,18 @@ //red off } #if OUTPUTENABLE - printf("AP : %f \n\r", VData.AP); - printf("Sync : %d \n\r", VData.vesselSync); + printf("\033[2A"); + printf("\rAP : %f\n\r", VData.AP); + //printf("TAp : %i \n\r", VData.TAp); + //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"); + //printf("LiqFuel : %f \n\r", VData.LiquidFuel); + float LiqFuelRem = VData.LiquidFuel/VData.LiquidFuelTot*100; + printf("Fuel Left : %f %%", LiqFuelRem); + //printf("Vsurf : %f", 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 } @@ -372,9 +394,9 @@ if (deadtime > IDLETIMER) { deadtimeOld = now; - Connected = false; + //Connected = false; LEDSAllOff(); - printf("No packets for a while... going Idle \n\r"); + printf("Is Sleeping? \r\n"); } } @@ -543,6 +565,10 @@ structSize = sizeof(VData); address = (uint16_t*)&VData; } + else if(id == 2) + { + //Status Packet + } else { printf("Bad Packet ID: %d", buffer[packetCheckState]); @@ -571,308 +597,13 @@ 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); - 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++) + if(VData.id == 1) { - 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]; + memcpy(address,payloadBuffer,structSize); + rx_len = 0; + return true; } - 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) - 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 {