diff --git a/TODO.md b/TODO.md index 7dd0824f..15e825f8 100644 --- a/TODO.md +++ b/TODO.md @@ -15,8 +15,6 @@ Items to complete before the first alpha release. # Medium priority Items to complete before the first beta release. -* for non GPS equipped devices, set time from phone -* GUI on oled hangs for a few seconds occasionally, but comes back * assign every "channel" a random shared 8 bit sync word (per 4.2.13.6 of datasheet) - use that word to filter packets before even checking CRC. This will ensure our CPU will only wake for packets on our "channel" * Note: we do not do address filtering at the chip level, because we might need to route for the mesh * Use the Periodic class for both position and user periodic broadcasts @@ -173,4 +171,10 @@ Items after the first final candidate release. * blink the power led less often * have radiohead ISR send messages to RX queue directly, to allow that thread to block until we have something to send * move lora rx/tx to own thread and block on IO -* keep our pseudo time moving forward even if we enter deep sleep (use esp32 rtc) \ No newline at end of file +* keep our pseudo time moving forward even if we enter deep sleep (use esp32 rtc) +* for non GPS equipped devices, set time from phone +* GUI on oled hangs for a few seconds occasionally, but comes back +* update local GPS position (but do not broadcast) at whatever rate the GPS is giving it +* don't send our times to other nodes +* don't trust times from other nodes +* draw compass rose based off local walking track \ No newline at end of file diff --git a/src/MeshService.cpp b/src/MeshService.cpp index 0f568159..17c56bd6 100644 --- a/src/MeshService.cpp +++ b/src/MeshService.cpp @@ -209,9 +209,6 @@ void MeshService::handleToRadio(std::string s) tv.tv_usec = 0; gps.perhapsSetRTC(&tv); - - // leave in for now FIXME - // r.variant.packet.payload.variant.position.time = 0; // Set it to the default value so that we don't waste bytes broadcasting it (other nodes will use their own time) } r.variant.packet.rx_time = gps.getValidTime(); // Record the time the packet arrived from the phone (so we update our nodedb for the local node) @@ -239,6 +236,10 @@ void MeshService::sendToMesh(MeshPacket *p) { nodeDB.updateFrom(*p); // update our local DB for this packet (because phone might have sent position packets etc...) + // Strip out any time information before sending packets to other nodes - to keep the wire size small (and because other nodes shouldn't trust it anyways) + if(p->has_payload && p->payload.which_variant == SubPacket_position_tag) + p->payload.variant.position.time = 0; + // Note: We might return !OK if our fifo was full, at that point the only option we have is to drop it if (radio.send(p) != ERRNO_OK) DEBUG_MSG("Dropped packet because send queue was full!\n"); diff --git a/src/screen.cpp b/src/screen.cpp index 7e4d9eb9..bcf3f0b1 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -223,6 +223,11 @@ inline double toRadians(double deg) return deg * PI / 180; } +inline double toDegrees(double r) +{ + return r * 180 / PI; +} + /** * Computes the bearing in degrees between two points on Earth. Ported from my old Gaggle android app. * @@ -285,11 +290,41 @@ void drawLine(OLEDDisplay *d, const Point &p1, const Point &p2) d->drawLine(p1.x, p1.y, p2.x, p2.y); } +/** + * Given a recent lat/lon return a guess of the heading the user is walking on. + * + * We keep a series of "after you've gone 10 meters, what is your heading since the last reference point?" + */ +float estimatedHeading(double lat, double lon) +{ + static double oldLat, oldLon; + static float b; + + if (oldLat == 0) + { + // just prepare for next time + oldLat = lat; + oldLon = lon; + + return b; + } + + float d = latLongToMeter(oldLat, oldLon, lat, lon); + if (d < 10) // haven't moved enough, just keep current bearing + return b; + + b = bearing(oldLat, oldLon, lat, lon); + oldLat = lat; + oldLon = lon; + + return b; +} + #define COMPASS_DIAM 44 /// We will skip one node - the one for us, so we just blindly loop over all nodes static size_t nodeIndex; -static uint8_t prevFrame = 0; +static int8_t prevFrame = -1; void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { @@ -345,7 +380,9 @@ void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, in snprintf(distStr, sizeof(distStr), "%.1f km", d / 1000); // FIXME, also keep the guess at the operators heading and add/substract it. currently we don't do this and instead draw north up only. - headingRadian = bearing(p.latitude, p.longitude, op.latitude, op.longitude); + float bearingToOther = bearing(p.latitude, p.longitude, op.latitude, op.longitude); + float myHeading = estimatedHeading(p.latitude, p.longitude); + headingRadian = bearingToOther - myHeading; } const char *fields[] = { @@ -631,6 +668,8 @@ void screen_set_frames() ui.setFrames(nonBootFrames, numframes); showingBluetooth = false; + + prevFrame = -1; // Force drawNodeInfo to pick a new node (because our list just changed) } /// handle press of the button