Files
Jakub 8f4c92a217 feat(sim): add variants/sim/ — real companion_radio firmware on native + Emscripten
New board variant compiling the unmodified MyMesh/UITask/DataStore app
logic against real mesh::Radio/MainBoard/RTCClock/RNG interfaces, for
running the actual firmware outside embedded hardware:

- Native (plain g++, platform = native): ASCII-art display over stdout,
  stdin-driven input, local-disk-backed DataStore/IdentityStore.
- Emscripten/WASM (variants/sim/build_wasm.sh, since PlatformIO's native
  platform force-overrides any CC/CXX toolchain override back to system
  clang++): canvas-backed display, IDBFS-backed persistence across page
  reloads, JS-callable input via sim_enqueue_key(), emscripten_set_main_loop.

Real rweather/Crypto (AES128/SHA256/Ed25519) vendored unmodified and
proven working on both targets. variants/sim/web/index.html is a bare
verification harness, not the polished website embed.
2026-09-03 00:46:47 +02:00

133 lines
4.5 KiB
C++

/*
* CayenneLPP - CayenneLPP Polyline Codec
*
* Copyright (C) 2021 by Manuel Weichselbaumer <mincequi@web.de>
*
* Use of this source code is governed by the MIT license that can be found in the LICENSE file.
*
*/
#ifndef CAYENNELPPPOLYLINE_H
#define CAYENNELPPPOLYLINE_H
#include <utility>
#include <vector>
// ESP-IDF framework
#if !defined(ARDUINO) && defined(IDF_VER)
#include <stdint.h>
#endif
struct DeltaCoord;
class CayenneLPPPolyline {
public:
enum Precision : uint8_t {
//Reserved = 200,
//Prec0_00001 = 224,
//Prec0_000025 = 225,
//Prec0_00005 = 226,
Prec0_0001 = 227,
Prec0_0002 = 228,
Prec0_0005 = 229,
Prec0_001 = 230,
Prec0_002 = 231,
Prec0_005 = 232,
Prec0_01 = 233,
Prec0_02 = 234,
Prec0_05 = 235,
Prec0_1 = 236,
Prec0_2 = 237,
Prec0_5 = 238,
Prec1_0 = 239,
//Prec2_0 = 240,
//Prec5_0 = 241,
//Reserved = 242
};
/**
* @brief The Simplification algorithm to apply
*/
enum Simplification {
None = 0, ///< No simplifaction applied
PerpendicularDistance = 1, ///< A simple and fast algorithm
DouglasPeucker = 2 ///< A sophisticated but complex algorithm
};
struct Stats {
uint32_t keptCoords = 0;
uint32_t addedCoords = 0;
uint32_t removedCoords = 0;
};
using Point = std::pair<double, double>;
CayenneLPPPolyline(uint32_t size);
/**
* @brief encode Encodes a set of GPS Coordinates into a byte buffer.
* The first pair of lat/lon will be encoded a a resolution of 0.0001 degrees, while subsequent
* pair will be encoded at lower resolutions as defined by a factor.
* @param coords The set of coords to be serialized and compressed.
* @param factor This factor is used as quantization factor for delta compression.
* A value of 1 results in a precision of 0.0001 degrees.
* This value scales linearly, so a value of 10 would result in a precision of 0.001 degrees.
* You can set values as high as 199.
* Special values start from 227 (see CayenneLPPPolyline::Precision).
* Values 200-226 and 240-255 are reserved for future usage.
* @param simplification The simplification to apply to coordinates.
* @return buffer The byte buffer which results from serialization.
*/
std::vector<uint8_t> encode(const std::vector<Point>& coords,
uint8_t factor,
Simplification simplification = DouglasPeucker);
/**
* @brief encode Encodes a set of GPS Coordinates into a byte buffer.
* @param coords The set of coords to be serialized and compressed.
* @param precision This defines the precision for delta compression (see CayenneLPPPolyline::Precision).
* @param simplification The simplification to apply to coordinates.
* @return buffer The byte buffer which results from serialization.
*/
std::vector<uint8_t> encode(const std::vector<Point>& coords,
Precision precision = Prec0_0001,
Simplification simplification = DouglasPeucker);
/**
* @brief decode Decodes a byte buffer back to a set of GPS Coordinates.
* @param buffer The byte buffer to be deserialized.
* @return coordinates The resulting coordinates from deserialization.
*/
static std::vector<std::pair<double, double>> decode(const std::vector<uint8_t>& buffer);
/**
* @brief getEncodeStats Obtain some statistics from the encoding process.
* @return stats The resulting statistics from encoding.
*/
Stats getEncodeStats() const;
private:
void reset();
static double getFactor(uint8_t factor);
void push(double lat, double lon, bool optimize);
void pushFirst(double lat, double lon, uint8_t factor);
void writeHeader(int32_t lat, int32_t lon, uint8_t factor);
void writeDelta(int8_t lat, int8_t lon, bool optimize);
static std::vector<Point> douglasPeucker(const std::vector<Point>& pointList, double epsilon);
static double distance(const Point& point, const Point& lineStart, const Point& lineEnd);
const uint32_t m_maxSize = 0;
std::vector<uint8_t> m_buffer;
double m_prevLat = 0.0;
double m_prevLon = 0.0;
double m_errLat = 0.0;
double m_errLon = 0.0;
Stats m_stats;
};
#endif // CAYENNELPPPOLYLINE_H