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
main.cpp
- Committer:
- wakestrap
- Date:
- 2020-03-14
- Revision:
- 15:03ed24574806
- Parent:
- 11:59dcefdda506
- Child:
- 16:0eda62f0d9e8
File content as of revision 15:03ed24574806:
#include "mbed.h" #include "EthernetInterface.h" #include <mbed.h> #include "Thread.h" /* ---------------------------------------------------------------------------------------- */ #define PORT 2342 #define DEBUG 1 #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; } */ DigitalIn press(USER_BUTTON); 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 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) { 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); } } int main() { EthernetInterface eth; 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()); //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]; 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; 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 KSP Server \n\r"); sock.send(HSPacket, sizeof(HSPacket)); while (sock.is_connected()) { char buffer[300]; int ret; ret = sock.receive(buffer, sizeof(buffer)-1); buffer[ret] = '\0'; if(ret > 0) { int CurrentState = 0; for (int x = 0; x < sizeof(buffer)-1; x++) { switch (CurrentState) { 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; } } #if DEBUG printf("Payload ID: %d \r\n", PayloadBuffer[0]); #endif if(PayloadBuffer[0] == 0) { } if(PayloadBuffer[0] == 1) { 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)); } else { } //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) 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"); } else { NavballSASMode = 0b00000000; } 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(); eth.disconnect(); while(1) {} }