From cff68452c7e5b7a671fc0f7c7b490b5de7415877 Mon Sep 17 00:00:00 2001 From: Kingkone Date: Mon, 18 Feb 2019 12:15:57 +0100 Subject: [PATCH] FC timeout, set debug GPS, readme --- README.md | 33 +++++--- docs/osd.jpg | Bin 0 -> 62358 bytes src/main.cpp | 214 ++++++++++++++++----------------------------------- src/main.h | 4 +- 4 files changed, 91 insertions(+), 160 deletions(-) create mode 100644 docs/osd.jpg diff --git a/README.md b/README.md index f8de593..39b0dd1 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ INAV-Radar is an addition to the [INAV](https://github.com/iNavFlight/inav) flight control software, it relays information about UAVs in the area to the flight controller for display on the OSD. INAV-Radar does this by using [LoRa](https://en.wikipedia.org/wiki/LoRa) radio to broadcast position, altitude, speed and plane name. It also listens for other UAVs so INAV OSD can display this information as a radar style map. +![Windows CMD output](https://github.com/mistyk/inavradar-ESP32/raw/master/docs/osd.jpg) + ## Hardware Current development is done using these cheap ESP32 LoRa modules. @@ -82,17 +84,26 @@ Via USB serial you get a small CLI with debug output. Also there are some commands: ``` -status show status -reboot reboot EPS32 -gpspos show GPS data -config shows current config -config loraFreq 433000000 sets lora frequency (Hz) -config loraBandwidth 250000 set lora bandwidth (Hz) -config uavtimeout 10 timeout for switched off UAVs (sec) -debug toggle debug output -radiofakeplanes makes the module send a fakeplane (somewhere in germany) -localfakeplanes makes the module send a fakeplane to connected FC -movefakeplanes moves the fakeplane +================= Commands ================= +status - Show whats going on +help - List all commands +config - List all settings +config loraFreq n - Set frequency in Hz (e.g. n = 433000000) +config loraBandwidth n - Set bandwidth in Hz (e.g. n = 250000) +config loraSpread n - Set SF (e.g. n = 10) +config uavtimeout n - Set UAV timeout in sec (e.g. n = 10) +config fctimeout n - Set FC timeout in sec (e.g. n = 5) +config debuglat n - Set debug GPS lat * 10000000 (e.g. n = 501004900) +config debuglon n - Set debug GPS lon * 10000000 (e.g. n = 87632280) +reboot - Reset MCU and radio +gpspos - Show last GPS position +debug - Toggle debug output +localfakeplanes - Send fake plane to FC +lfp - Send fake plane to FC +radiofakeplanes - Send fake plane via radio +rfp - Send fake plane via radio +movefakeplanes - Move fake plane +mfp - Move fake plane ``` Attention !!! On Windows with Putty you must use [CRTL]-[J] insted of the [ENTER] key. diff --git a/docs/osd.jpg b/docs/osd.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8c896ac9afd70fd7198053df75d2e8cdd68d34ec GIT binary patch literal 62358 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 E*&8JqRsaA1 literal 0 HcmV?d00001 diff --git a/src/main.cpp b/src/main.cpp index ada96f3..d8d4c9c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,7 +15,7 @@ using namespace simplecli; #define RST 14 // GPIO14 - SX1278's RESET #define DI0 26 // GPIO26 - SX1278's IRQ (interrupt request) -#define CFGVER 11 // bump up to overwrite setting with new defaults +#define CFGVER 12 // bump up to overwrite setting with new defaults // ----------------------------------------------------------------------------- global vars config cfg; MSP msp; @@ -29,17 +29,17 @@ long sendLastTime = 0; long displayLastTime = 0; long pdLastTime = 0; -msp_analog_t fcanalog; -msp_status_ex_t fcstatusex; +msp_analog_t fcanalog; // analog values from FC +msp_status_ex_t fcstatusex; // extended status from FC msp_raw_gps_t homepos; // set on arm planeData pd; // our uav data planeData pdIn; // new air packet +planeData loraMsg; // incoming packet planesData pds[5]; // uav db -planeData fakepd; // debugging +planeData fakepd; // debugging plane char planeFC[20]; // uav fc name bool loraRX = 0; // display RX bool loraTX = 0; // display TX -planeData loraMsg; // incoming packet int numPlanes = 0; String rssi = "0"; bool buttonState = 1; @@ -73,6 +73,7 @@ void initConfig () { cfg.intervalDisplay = 100; // in ms cfg.intervalStatus = 1000; // in ms cfg.uavTimeout = 10; // in sec + cfg.fcTimeout = 5; // in sec cfg.mspTX = 23; // pin for msp serial TX cfg.mspRX = 17; // pin for msp serial RX cfg.mspPOI = 1; // POI type: 1 (Wayponit), 2 (Plane) # TODO @@ -80,6 +81,8 @@ void initConfig () { cfg.debugFakeWPs = false; cfg.debugFakePlanes = false; cfg.debugFakeMoving = false; + cfg.debugGpsLat = 50.100400 * 10000000; + cfg.debugGpsLon = 8.762835 * 10000000; EEPROM.begin(size * 2); for(size_t i = 0; i < size; i++) { char data = ((char *)&cfg)[i]; @@ -96,12 +99,10 @@ void initConfig () { #include #define earthRadiusKm 6371.0 -// This function converts decimal degrees to radians double deg2rad(double deg) { return (deg * M_PI / 180); } -// This function converts radians to decimal degrees double rad2deg(double rad) { return (rad * 180 / M_PI); } @@ -126,13 +127,10 @@ double distanceEarth(double lat1d, double lon1d, double lat2d, double lon2d) { return 2.0 * earthRadiusKm * asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v)); } // ----------------------------------------------------------------------------- String split - -String getValue(String data, char separator, int index) -{ +String getValue(String data, char separator, int index) { int found = 0; int strIndex[] = { 0, -1 }; int maxIndex = data.length() - 1; - for (int i = 0; i <= maxIndex && found <= index; i++) { if (data.charAt(i) == separator || i == maxIndex) { found++; @@ -197,21 +195,29 @@ void cliStatus(int n) { } void cliHelp(int n) { serialConsole[n]->println("================= Commands ================="); - serialConsole[n]->println("status - Show whats going on"); - serialConsole[n]->println("help - List all commands"); - serialConsole[n]->println("config - List all settings"); - serialConsole[n]->println("reboot - Reset MCU and radio"); - serialConsole[n]->println("gpspos - Show last GPS position"); - //serialConsole[n]->println("fcpass - start FC passthru mode"); - serialConsole[n]->println("debug - Toggle debug output"); - serialConsole[n]->println("localfakeplanes - Send fake planes to FC"); - serialConsole[n]->println("radiofakeplanes - Send fake planes via radio"); - serialConsole[n]->println("movefakeplanes - Move fake planes"); + serialConsole[n]->println("status - Show whats going on"); + serialConsole[n]->println("help - List all commands"); + serialConsole[n]->println("config - List all settings"); + serialConsole[n]->println("config loraFreq n - Set frequency in Hz (e.g. n = 433000000)"); + serialConsole[n]->println("config loraBandwidth n - Set bandwidth in Hz (e.g. n = 250000)"); + serialConsole[n]->println("config loraSpread n - Set SF (e.g. n = 10)"); + serialConsole[n]->println("config uavtimeout n - Set UAV timeout in sec (e.g. n = 10)"); + serialConsole[n]->println("config fctimeout n - Set FC timeout in sec (e.g. n = 5)"); + serialConsole[n]->println("config debuglat n - Set debug GPS lat * 10000000 (e.g. n = 501004900)"); + serialConsole[n]->println("config debuglon n - Set debug GPS lon * 10000000 (e.g. n = 87632280)"); + serialConsole[n]->println("reboot - Reset MCU and radio"); + serialConsole[n]->println("gpspos - Show last GPS position"); + //serialConsole[n]->println("fcpass - start FC passthru mode"); + serialConsole[n]->println("debug - Toggle debug output"); + serialConsole[n]->println("localfakeplanes - Send fake plane to FC"); + serialConsole[n]->println("lfp - Send fake plane to FC"); + serialConsole[n]->println("radiofakeplanes - Send fake plane via radio"); + serialConsole[n]->println("rfp - Send fake plane via radio"); + serialConsole[n]->println("movefakeplanes - Move fake plane"); + serialConsole[n]->println("mfp - Move fake plane"); } void cliConfig(int n) { serialConsole[n]->println("=============== Configuration =============="); - serialConsole[n]->print("Lora local address: "); - serialConsole[n]->println(cfg.loraAddress); serialConsole[n]->print("Lora frequency: "); serialConsole[n]->print(cfg.loraFrequency); serialConsole[n]->println(" Hz"); @@ -224,6 +230,8 @@ void cliConfig(int n) { serialConsole[n]->println(cfg.loraCodingRate4); serialConsole[n]->print("UAV timeout: "); serialConsole[n]->print(cfg.uavTimeout); + serialConsole[n]->print("FC timeout: "); + serialConsole[n]->print(cfg.fcTimeout); serialConsole[n]->println(" sec"); serialConsole[n]->print("MSP RX pin: "); serialConsole[n]->println(cfg.mspRX); @@ -231,6 +239,10 @@ void cliConfig(int n) { serialConsole[n]->println(cfg.mspTX); serialConsole[n]->print("Debug output: "); serialConsole[n]->println(cfg.debugOutput ? "ON" : "OFF"); + serialConsole[n]->print("Debug GPS lat: "); + serialConsole[n]->println(cfg.debugGpsLat); + serialConsole[n]->print("Debug GPS lat: "); + serialConsole[n]->println(cfg.debugGpsLon); serialConsole[n]->print("Local fake planes: "); serialConsole[n]->println(cfg.debugFakeWPs ? "ON" : "OFF"); serialConsole[n]->print("Radio fake planes: "); @@ -290,6 +302,9 @@ void initCli () { cli->addCmd(new Command("localfakeplanes", [](Cmd* cmd) { cliLocalFake(cNum); } )); cli->addCmd(new Command("radiofakeplanes", [](Cmd* cmd) { cliRadioFake(cNum); } )); cli->addCmd(new Command("movefakeplanes", [](Cmd* cmd) { cliMoveFake(cNum); } )); + cli->addCmd(new Command("lfp", [](Cmd* cmd) { cliLocalFake(cNum); } )); + cli->addCmd(new Command("rfp", [](Cmd* cmd) { cliRadioFake(cNum); } )); + cli->addCmd(new Command("mfp", [](Cmd* cmd) { cliMoveFake(cNum); } )); cli->addCmd(new Command("reboot", [](Cmd* cmd) { cliReboot(cNum); } )); cli->addCmd(new Command("gpspos", [](Cmd* cmd) { cliGPSpos(cNum); } )); @@ -324,13 +339,13 @@ void initCli () { serialConsole[cNum]->println("Lora Lora spreading factor not correct: 7 - 12"); } } - if (arg1 == "loraAddress") { + if (arg1 == "fctimeonut") { if (arg2.toInt() >= 1 && arg2.toInt() <= 250) { - cfg.loraAddress = arg2.toInt(); + cfg.fcTimeout = arg2.toInt(); saveConfig(); - serialConsole[cNum]->println("Lora address changed!"); + serialConsole[cNum]->println("FC timout changed!"); } else { - serialConsole[cNum]->println("Lora address not correct: 1 - 250"); + serialConsole[cNum]->println("FC timout not correct: 1 - 250"); } } if (arg1 == "uavtimeout") { @@ -342,6 +357,24 @@ void initCli () { serialConsole[cNum]->println("UAV timeout not correct: 5 - 600"); } } + if (arg1 == "debuglat") { + if (arg2.toInt() >= 0) { + cfg.debugGpsLat = arg2.toInt(); + saveConfig(); + serialConsole[cNum]->println("Debug GPS lat changed!"); + } else { + serialConsole[cNum]->println("ebug GPS lat not correct: lat * 10000000"); + } + } + if (arg1 == "debuglon") { + if (arg2.toInt() >= 0) { + cfg.debugGpsLat = arg2.toInt(); + saveConfig(); + serialConsole[cNum]->println("Debug GPS lon changed!"); + } else { + serialConsole[cNum]->println("ebug GPS lon not correct: lon * 10000000"); + } + } }); config->addArg(new AnonymOptArg("")); config->addArg(new AnonymOptArg("")); @@ -404,51 +437,11 @@ void sendFakePlanes () { fakepd.loraAddress = (char)5; String("Testplane #1").toCharArray(fakepd.planeName,20); fakepd.state= 1; -// fakepd.gps.lat = homepos.lat + (10 * moving); -// fakepd.gps.lon = homepos.lon; fakepd.gps.alt = 300; fakepd.gps.groundSpeed = 450; - //sendMessage(&fakepd); - //delay(300); - /* - fakepd.loraAddress = (char)2; - String("Testplane #2").toCharArray(fakepd.planeName,20); - fakepd.armState= 1; */ - // -------------------------------------------------------- fixed GPS pos radio fake planes - - fakepd.gps.lat = 50.100400 * 10000000; // + (500 * moving); - fakepd.gps.lon = 8.762835 * 10000000; - sendMessage(&fakepd); - // 50.088233, 8.782278 ... 50.088233, 8.785693 ... 341 * 100 - // 50.100400, 8.762835 - // 50.101938, 8.812962 - bieber - // 47.345446, -1.543392 - /* - delay(300); - fakepd.loraAddress = (char)3; - String("Testplane #3").toCharArray(fakepd.planeName,20); - fakepd.gps.alt = 500; - fakepd.armState= 1; - fakepd.gps.lat = 50.088233 * 10000000; - fakepd.gps.lon = 8.782278 * 10000000 + (341 * moving); - sendMessage(&fakepd); - delay(300); - fakepd.loraAddress = (char)4; - String("Testplane #4").toCharArray(fakepd.planeName,20); - fakepd.armState= 1; - fakepd.gps.lat = 50.088233 * 10000000; - fakepd.gps.lon = 8.782278 * 10000000 + (600 * moving); - fakepd.gps.alt = 500; - sendMessage(&fakepd); - delay(300); - fakepd.loraAddress = (char)5; - String("Testplane #5").toCharArray(fakepd.planeName,20); - fakepd.armState= 1; - fakepd.gps.lat = 50.1006770 * 10000000 + (1000 * moving); - fakepd.gps.lon = 8.762406 * 10000000; + fakepd.gps.lat = cfg.debugGpsLat + (500 * moving); + fakepd.gps.lon = cfg.debugGpsLon; sendMessage(&fakepd); - delay(300); -*/ cliLog("Fake UAVs sent."); moving++; } @@ -505,6 +498,7 @@ void drawDisplay () { } else { //if (bitRead(fcstatusex.armingFlags,17) == 0) display.drawString (0,54, "RC LINK LOST"); //else + // TODO display.drawString (0,54, pd.planeName); if (fcstatusex.armingFlags != 0) display.drawXbm(61, 54, 8, 8, warnSymbol); } @@ -512,7 +506,6 @@ void drawDisplay () { display.drawString (106,54, "RX"); display.drawXbm(98, 55, 8, 8, loraTX ? activeSymbol : inactiveSymbol); display.drawXbm(120, 55, 8, 8, loraRX ? activeSymbol : inactiveSymbol); - } if (displayPage == 1) { if (numPlanes == 0) display.drawString (0,0, "no UAVs detected ..."); @@ -543,26 +536,6 @@ void drawDisplay () { } } } - - /* old display - display.setFont (ArialMT_Plain_10); - display.setTextAlignment (TEXT_ALIGN_LEFT); - display.drawString (0,54, pd.armState ? "Armed" : "Disarmed"); - display.drawString (48,54, String(pd.gps.numSat) + " Sat"); - display.drawString (84,54, "TX"); - display.drawString (106,54, "RX"); - - display.drawXbm(98, 55, 8, 8, loraTX ? activeSymbol : inactiveSymbol); - display.drawXbm(120, 55, 8, 8, loraRX ? activeSymbol : inactiveSymbol); - - for (size_t i = 0; i <=4 ; i++) { - if (pds[i].waypointNumber != 0) { - display.drawString (0,i*8, pds[i].pd.planeName); - display.drawString (80,i*8,String(pds[i].distance)); - } - } - */ - display.display(); } @@ -664,50 +637,10 @@ void planeFakeWP () { msp_set_wp_t wp; if (cfg.debugFakeMoving && moving > 100) { moving = 0; - } else { + } + if (!cfg.debugFakeMoving) { moving = 0; } -/* wp.waypointNumber = 1; - wp.action = MSP_NAV_STATUS_WAYPOINT_ACTION_WAYPOINT; - wp.lat = 50.1006770 * 10000000; - wp.lon = 8.7613380 * 10000000; - wp.alt = 100; - wp.p1 = 200; - wp.p2 = 0; - wp.p3 = 0; - wp.flag = 0; - msp.command(MSP_SET_WP, &wp, sizeof(wp)); - wp.waypointNumber = 2; - wp.action = MSP_NAV_STATUS_WAYPOINT_ACTION_WAYPOINT; - wp.lat = 50.1020320 * 10000000; - wp.lon = 8.7615830 * 10000000; - wp.alt = 200; - wp.p1 = 100; - wp.p2 = 0; - wp.p3 = 0; - wp.flag = 0; - msp.command(MSP_SET_WP, &wp, sizeof(wp)); - wp.waypointNumber = 3; - wp.action = MSP_NAV_STATUS_WAYPOINT_ACTION_WAYPOINT; - wp.lat = 50.102137 * 10000000; - wp.lon = 8.762990 * 10000000; - wp.alt = 300; - wp.p1 = 0; - wp.p2 = 0; - wp.p3 = 0; - wp.flag = 0; - msp.command(MSP_SET_WP, &wp, sizeof(wp)); - wp.waypointNumber = 4; - wp.action = MSP_NAV_STATUS_WAYPOINT_ACTION_WAYPOINT; - wp.lat = 50.100547 * 10000000; - wp.lon = 8.764052 * 10000000; - wp.alt = 0; - wp.p1 = 500; - wp.p2 = 0; - wp.p3 = 0; - wp.flag = 0; - msp.command(MSP_SET_WP, &wp, sizeof(wp)); -*/ if (pd.gps.fixType > 0) { wp.waypointNumber = 1; @@ -739,7 +672,7 @@ void initMSP () { display.drawString (0, 24, "FC "); display.display(); cliLog("Waiting for FC to start ..."); - delay(2000); + delay(cfg.fcTimeout*1000); getPlaneData(); //getPlanetArmed(); getPlaneGPS(); @@ -769,13 +702,6 @@ void IRAM_ATTR handleInterrupt() { void setup() { - -/* cli.RegisterCmd("status",&cliStatus); - cli.RegisterCmd("help",&cliHelp); - cli.RegisterCmd("config",&cliConfig); - cli.RegisterCmd("debug",&cliDebug); - cli.RegisterCmd("reboot",&cliReboot); */ - Serial.begin(115200); serialConsole[0] = &Serial; initCli(); @@ -785,7 +711,6 @@ void setup() { delay(1500); initMSP(); delay(1000); - //wifisetup(); pinMode(interruptPin, INPUT); buttonPressed = 0; attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, RISING); @@ -800,7 +725,6 @@ void setup() { // ----------------------------------------------------------------------------- main loop void loop() { - if ( (millis() - lastDebounceTime) > 150 && buttonPressed == 1) buttonPressed = 0; if (millis() - displayLastTime > cfg.intervalDisplay) { @@ -818,9 +742,6 @@ void loop() { if (pds[i].waypointNumber != 0) numPlanes++; if (pd.gps.fixType != 0) pds[i].distance = distanceEarth(pd.gps.lat/10000000, pd.gps.lon/10000000, pds[i].pd.gps.lat/10000000, pds[i].pd.gps.lon/10000000); if (pds[i].pd.loraAddress != 0 && millis() - pds[i].lastUpdate > cfg.uavTimeout*1000 ) { // plane timeout - //pds[i].pd.gps.lat = 0; - //pds[i].pd.gps.lon = 0; - //pds[i].pd.gps.alt = 0; pds[i].pd.state = 2; planeSetWP(); planeSetWP(); @@ -832,14 +753,12 @@ void loop() { } } getPlaneStatusEx(); - //dalternate = !dalternate; if (String(pd.planeName) != "No Name" ) { getPlaneData(); getPlanetArmed(); getPlaneBat(); if (!pd.state) { getPlaneGPS(); - } } @@ -870,6 +789,5 @@ void loop() { //if (pd.armState) planeSetWP(); planeSetWP(); if (cfg.debugFakeWPs) planeFakeWP(); - //planeFakeWPv2(); } } diff --git a/src/main.h b/src/main.h index b50ddf7..f002d2a 100644 --- a/src/main.h +++ b/src/main.h @@ -10,14 +10,16 @@ struct config { uint16_t intervalDisplay; // in ms uint16_t intervalStatus; // in ms uint16_t uavTimeout; // in sec + uint8_t fcTimeout; // in sec uint8_t mspTX; // pin for msp serial TX uint8_t mspRX; // pin for msp serial RX uint8_t mspPOI; // POI type: 1 (Wayponit), 2 (Plane) - bool debugOutput; bool debugFakeWPs; bool debugFakePlanes; bool debugFakeMoving; + int32_t debugGpsLat; // decimal degrees lat * 10000000 + int32_t debugGpsLon; // decimal degrees lon * 10000000 }; struct planeData {