mirror of
https://github.com/meshtastic/firmware.git
synced 2025-08-11 16:07:13 +00:00
CompassRenderer methods
This commit is contained in:
parent
6f922641b2
commit
6e376aeea6
@ -755,35 +755,6 @@ float Screen::estimatedHeading(double lat, double lon)
|
|||||||
/// nodes
|
/// nodes
|
||||||
static int8_t prevFrame = -1;
|
static int8_t prevFrame = -1;
|
||||||
|
|
||||||
// Draw the arrow pointing to a node's location
|
|
||||||
void Screen::drawNodeHeading(OLEDDisplay *display, int16_t compassX, int16_t compassY, uint16_t compassDiam, float headingRadian)
|
|
||||||
{
|
|
||||||
Point tip(0.0f, 0.5f), tail(0.0f, -0.35f); // pointing up initially
|
|
||||||
float arrowOffsetX = 0.14f, arrowOffsetY = 1.0f;
|
|
||||||
Point leftArrow(tip.x - arrowOffsetX, tip.y - arrowOffsetY), rightArrow(tip.x + arrowOffsetX, tip.y - arrowOffsetY);
|
|
||||||
|
|
||||||
Point *arrowPoints[] = {&tip, &tail, &leftArrow, &rightArrow};
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
arrowPoints[i]->rotate(headingRadian);
|
|
||||||
arrowPoints[i]->scale(compassDiam * 0.6);
|
|
||||||
arrowPoints[i]->translate(compassX, compassY);
|
|
||||||
}
|
|
||||||
/* Old arrow
|
|
||||||
display->drawLine(tip.x, tip.y, tail.x, tail.y);
|
|
||||||
display->drawLine(leftArrow.x, leftArrow.y, tip.x, tip.y);
|
|
||||||
display->drawLine(rightArrow.x, rightArrow.y, tip.x, tip.y);
|
|
||||||
display->drawLine(leftArrow.x, leftArrow.y, tail.x, tail.y);
|
|
||||||
display->drawLine(rightArrow.x, rightArrow.y, tail.x, tail.y);
|
|
||||||
*/
|
|
||||||
#ifdef USE_EINK
|
|
||||||
display->drawTriangle(tip.x, tip.y, rightArrow.x, rightArrow.y, tail.x, tail.y);
|
|
||||||
#else
|
|
||||||
display->fillTriangle(tip.x, tip.y, rightArrow.x, rightArrow.y, tail.x, tail.y);
|
|
||||||
#endif
|
|
||||||
display->drawTriangle(tip.x, tip.y, leftArrow.x, leftArrow.y, tail.x, tail.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get a string representation of the time passed since something happened
|
// Get a string representation of the time passed since something happened
|
||||||
void Screen::getTimeAgoStr(uint32_t agoSecs, char *timeStr, uint8_t maxLength)
|
void Screen::getTimeAgoStr(uint32_t agoSecs, char *timeStr, uint8_t maxLength)
|
||||||
{
|
{
|
||||||
@ -814,55 +785,6 @@ void Screen::getTimeAgoStr(uint32_t agoSecs, char *timeStr, uint8_t maxLength)
|
|||||||
snprintf(timeStr, maxLength, "unknown age");
|
snprintf(timeStr, maxLength, "unknown age");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t compassY, float myHeading)
|
|
||||||
{
|
|
||||||
Serial.print("🧭 [Main Compass] Raw Heading (deg): ");
|
|
||||||
Serial.println(myHeading * RAD_TO_DEG);
|
|
||||||
|
|
||||||
// If north is supposed to be at the top of the compass we want rotation to be +0
|
|
||||||
if (config.display.compass_north_top)
|
|
||||||
myHeading = -0;
|
|
||||||
/* N sign points currently not deleted*/
|
|
||||||
Point N1(-0.04f, 0.65f), N2(0.04f, 0.65f); // N sign points (N1-N4)
|
|
||||||
Point N3(-0.04f, 0.55f), N4(0.04f, 0.55f);
|
|
||||||
Point NC1(0.00f, 0.50f); // north circle center point
|
|
||||||
Point *rosePoints[] = {&N1, &N2, &N3, &N4, &NC1};
|
|
||||||
|
|
||||||
uint16_t compassDiam = Screen::getCompassDiam(SCREEN_WIDTH, SCREEN_HEIGHT);
|
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
// North on compass will be negative of heading
|
|
||||||
rosePoints[i]->rotate(-myHeading);
|
|
||||||
rosePoints[i]->scale(compassDiam);
|
|
||||||
rosePoints[i]->translate(compassX, compassY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t Screen::getCompassDiam(uint32_t displayWidth, uint32_t displayHeight)
|
|
||||||
{
|
|
||||||
uint16_t diam = 0;
|
|
||||||
uint16_t offset = 0;
|
|
||||||
|
|
||||||
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT)
|
|
||||||
offset = FONT_HEIGHT_SMALL;
|
|
||||||
|
|
||||||
// get the smaller of the 2 dimensions and subtract 20
|
|
||||||
if (displayWidth > (displayHeight - offset)) {
|
|
||||||
diam = displayHeight - offset;
|
|
||||||
// if 2/3 of the other size would be smaller, use that
|
|
||||||
if (diam > (displayWidth * 2 / 3)) {
|
|
||||||
diam = displayWidth * 2 / 3;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
diam = displayWidth;
|
|
||||||
if (diam > ((displayHeight - offset) * 2 / 3)) {
|
|
||||||
diam = (displayHeight - offset) * 2 / 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return diam - 20;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Combined dynamic node list frame cycling through LastHeard, HopSignal, and Distance modes
|
// Combined dynamic node list frame cycling through LastHeard, HopSignal, and Distance modes
|
||||||
// Uses a single frame and changes data every few seconds (E-Ink variant is separate)
|
// Uses a single frame and changes data every few seconds (E-Ink variant is separate)
|
||||||
|
|
||||||
|
@ -238,14 +238,8 @@ class Screen : public concurrency::OSThread
|
|||||||
void getTimeAgoStr(uint32_t agoSecs, char *timeStr, uint8_t maxLength);
|
void getTimeAgoStr(uint32_t agoSecs, char *timeStr, uint8_t maxLength);
|
||||||
|
|
||||||
// Draw north
|
// Draw north
|
||||||
void drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t compassY, float myHeading);
|
|
||||||
|
|
||||||
static uint16_t getCompassDiam(uint32_t displayWidth, uint32_t displayHeight);
|
|
||||||
|
|
||||||
float estimatedHeading(double lat, double lon);
|
float estimatedHeading(double lat, double lon);
|
||||||
|
|
||||||
void drawNodeHeading(OLEDDisplay *display, int16_t compassX, int16_t compassY, uint16_t compassDiam, float headingRadian);
|
|
||||||
|
|
||||||
void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char **fields);
|
void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char **fields);
|
||||||
|
|
||||||
/// Handle button press, trackball or swipe action)
|
/// Handle button press, trackball or swipe action)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "UIRenderer.h"
|
#include "UIRenderer.h"
|
||||||
|
#include "CompassRenderer.h"
|
||||||
#include "GPSStatus.h"
|
#include "GPSStatus.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "NodeListRenderer.h"
|
#include "NodeListRenderer.h"
|
||||||
@ -451,7 +452,7 @@ void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, in
|
|||||||
const auto &op = ourNode->position;
|
const auto &op = ourNode->position;
|
||||||
float myHeading = screen->hasHeading() ? screen->getHeading() * PI / 180
|
float myHeading = screen->hasHeading() ? screen->getHeading() * PI / 180
|
||||||
: screen->estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
|
: screen->estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
|
||||||
screen->drawCompassNorth(display, compassX, compassY, myHeading);
|
CompassRenderer::drawCompassNorth(display, compassX, compassY, myHeading);
|
||||||
|
|
||||||
const auto &p = node->position;
|
const auto &p = node->position;
|
||||||
float d =
|
float d =
|
||||||
@ -459,7 +460,7 @@ void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, in
|
|||||||
float bearing = GeoCoord::bearing(DegD(op.latitude_i), DegD(op.longitude_i), DegD(p.latitude_i), DegD(p.longitude_i));
|
float bearing = GeoCoord::bearing(DegD(op.latitude_i), DegD(op.longitude_i), DegD(p.latitude_i), DegD(p.longitude_i));
|
||||||
if (!config.display.compass_north_top)
|
if (!config.display.compass_north_top)
|
||||||
bearing -= myHeading;
|
bearing -= myHeading;
|
||||||
screen->drawNodeHeading(display, compassX, compassY, compassDiam, bearing);
|
CompassRenderer::drawNodeHeading(display, compassX, compassY, compassDiam, bearing);
|
||||||
|
|
||||||
display->drawCircle(compassX, compassY, compassRadius);
|
display->drawCircle(compassX, compassY, compassRadius);
|
||||||
}
|
}
|
||||||
@ -498,7 +499,7 @@ void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, in
|
|||||||
const auto &op = ourNode->position;
|
const auto &op = ourNode->position;
|
||||||
float myHeading = screen->hasHeading() ? screen->getHeading() * PI / 180
|
float myHeading = screen->hasHeading() ? screen->getHeading() * PI / 180
|
||||||
: screen->estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
|
: screen->estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
|
||||||
screen->drawCompassNorth(display, compassX, compassY, myHeading);
|
graphics::CompassRenderer::drawCompassNorth(display, compassX, compassY, myHeading);
|
||||||
|
|
||||||
const auto &p = node->position;
|
const auto &p = node->position;
|
||||||
float d =
|
float d =
|
||||||
@ -506,7 +507,7 @@ void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, in
|
|||||||
float bearing = GeoCoord::bearing(DegD(op.latitude_i), DegD(op.longitude_i), DegD(p.latitude_i), DegD(p.longitude_i));
|
float bearing = GeoCoord::bearing(DegD(op.latitude_i), DegD(op.longitude_i), DegD(p.latitude_i), DegD(p.longitude_i));
|
||||||
if (!config.display.compass_north_top)
|
if (!config.display.compass_north_top)
|
||||||
bearing -= myHeading;
|
bearing -= myHeading;
|
||||||
screen->drawNodeHeading(display, compassX, compassY, compassRadius * 2, bearing);
|
graphics::CompassRenderer::drawNodeHeading(display, compassX, compassY, compassRadius * 2, bearing);
|
||||||
|
|
||||||
display->drawCircle(compassX, compassY, compassRadius);
|
display->drawCircle(compassX, compassY, compassRadius);
|
||||||
}
|
}
|
||||||
@ -1014,7 +1015,7 @@ void drawCompassAndLocationScreen(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
// Center vertically and nudge down slightly to keep "N" clear of header
|
// Center vertically and nudge down slightly to keep "N" clear of header
|
||||||
const int16_t compassY = topY + (usableHeight / 2) + ((FONT_HEIGHT_SMALL - 1) / 2) + 2;
|
const int16_t compassY = topY + (usableHeight / 2) + ((FONT_HEIGHT_SMALL - 1) / 2) + 2;
|
||||||
|
|
||||||
screen->drawNodeHeading(display, compassX, compassY, compassDiam, -heading);
|
CompassRenderer::drawNodeHeading(display, compassX, compassY, compassDiam, -heading);
|
||||||
display->drawCircle(compassX, compassY, compassRadius);
|
display->drawCircle(compassX, compassY, compassRadius);
|
||||||
|
|
||||||
// "N" label
|
// "N" label
|
||||||
@ -1055,7 +1056,7 @@ void drawCompassAndLocationScreen(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
int compassX = x + SCREEN_WIDTH / 2;
|
int compassX = x + SCREEN_WIDTH / 2;
|
||||||
int compassY = yBelowContent + availableHeight / 2;
|
int compassY = yBelowContent + availableHeight / 2;
|
||||||
|
|
||||||
screen->drawNodeHeading(display, compassX, compassY, compassRadius * 2, -heading);
|
CompassRenderer::drawNodeHeading(display, compassX, compassY, compassRadius * 2, -heading);
|
||||||
display->drawCircle(compassX, compassY, compassRadius);
|
display->drawCircle(compassX, compassY, compassRadius);
|
||||||
|
|
||||||
// "N" label
|
// "N" label
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "PowerFSM.h"
|
#include "PowerFSM.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
#include "graphics/draw/CompassRenderer.h"
|
||||||
|
|
||||||
#if HAS_SCREEN
|
#if HAS_SCREEN
|
||||||
#include "gps/RTC.h"
|
#include "gps/RTC.h"
|
||||||
#include "graphics/Screen.h"
|
#include "graphics/Screen.h"
|
||||||
@ -119,7 +121,7 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state,
|
|||||||
|
|
||||||
// Dimensions / co-ordinates for the compass/circle
|
// Dimensions / co-ordinates for the compass/circle
|
||||||
int16_t compassX = 0, compassY = 0;
|
int16_t compassX = 0, compassY = 0;
|
||||||
uint16_t compassDiam = graphics::Screen::getCompassDiam(display->getWidth(), display->getHeight());
|
uint16_t compassDiam = graphics::CompassRenderer::getCompassDiam(display->getWidth(), display->getHeight());
|
||||||
|
|
||||||
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
|
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
|
||||||
compassX = x + display->getWidth() - compassDiam / 2 - 5;
|
compassX = x + display->getWidth() - compassDiam / 2 - 5;
|
||||||
@ -137,7 +139,7 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state,
|
|||||||
myHeading = (screen->getHeading()) * PI / 180; // gotta convert compass degrees to Radians
|
myHeading = (screen->getHeading()) * PI / 180; // gotta convert compass degrees to Radians
|
||||||
else
|
else
|
||||||
myHeading = screen->estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
|
myHeading = screen->estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
|
||||||
screen->drawCompassNorth(display, compassX, compassY, myHeading);
|
graphics::CompassRenderer::drawCompassNorth(display, compassX, compassY, myHeading);
|
||||||
|
|
||||||
// Compass bearing to waypoint
|
// Compass bearing to waypoint
|
||||||
float bearingToOther =
|
float bearingToOther =
|
||||||
@ -146,7 +148,7 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state,
|
|||||||
// If the top of the compass is not a static north we need adjust bearingToOther based on heading
|
// If the top of the compass is not a static north we need adjust bearingToOther based on heading
|
||||||
if (!config.display.compass_north_top)
|
if (!config.display.compass_north_top)
|
||||||
bearingToOther -= myHeading;
|
bearingToOther -= myHeading;
|
||||||
screen->drawNodeHeading(display, compassX, compassY, compassDiam, bearingToOther);
|
graphics::CompassRenderer::drawNodeHeading(display, compassX, compassY, compassDiam, bearingToOther);
|
||||||
|
|
||||||
float bearingToOtherDegrees = (bearingToOther < 0) ? bearingToOther + 2 * PI : bearingToOther;
|
float bearingToOtherDegrees = (bearingToOther < 0) ? bearingToOther + 2 * PI : bearingToOther;
|
||||||
bearingToOtherDegrees = bearingToOtherDegrees * 180 / PI;
|
bearingToOtherDegrees = bearingToOtherDegrees * 180 / PI;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "MotionSensor.h"
|
#include "MotionSensor.h"
|
||||||
|
#include "graphics/draw/CompassRenderer.h"
|
||||||
|
|
||||||
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C
|
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C
|
||||||
|
|
||||||
@ -48,7 +49,7 @@ void MotionSensor::drawFrameCalibration(OLEDDisplay *display, OLEDDisplayUiState
|
|||||||
display->drawString(x, y + 40, timeRemainingBuffer);
|
display->drawString(x, y + 40, timeRemainingBuffer);
|
||||||
|
|
||||||
int16_t compassX = 0, compassY = 0;
|
int16_t compassX = 0, compassY = 0;
|
||||||
uint16_t compassDiam = graphics::Screen::getCompassDiam(display->getWidth(), display->getHeight());
|
uint16_t compassDiam = graphics::CompassRenderer::getCompassDiam(display->getWidth(), display->getHeight());
|
||||||
|
|
||||||
// coordinates for the center of the compass/circle
|
// coordinates for the center of the compass/circle
|
||||||
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
|
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
|
||||||
@ -59,7 +60,7 @@ void MotionSensor::drawFrameCalibration(OLEDDisplay *display, OLEDDisplayUiState
|
|||||||
compassY = y + FONT_HEIGHT_SMALL + (display->getHeight() - FONT_HEIGHT_SMALL) / 2;
|
compassY = y + FONT_HEIGHT_SMALL + (display->getHeight() - FONT_HEIGHT_SMALL) / 2;
|
||||||
}
|
}
|
||||||
display->drawCircle(compassX, compassY, compassDiam / 2);
|
display->drawCircle(compassX, compassY, compassDiam / 2);
|
||||||
screen->drawCompassNorth(display, compassX, compassY, screen->getHeading() * PI / 180);
|
graphics::CompassRenderer::drawCompassNorth(display, compassX, compassY, screen->getHeading() * PI / 180);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user