Record gps lat, lon, satinuse from recorder app if there was gps signal. (#1992)

* Record gps lat, lon, satinuse from recorder app if there was gps signal.

* Add _GEO to filename that has geotag
This commit is contained in:
Totoo 2024-03-15 14:56:20 +01:00 committed by GitHub
parent 181624daf1
commit 9e40e38f07
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 90 additions and 6 deletions

View File

@ -461,6 +461,15 @@ std::string path::string() const {
return conv.to_bytes(native());
}
// appends a string to the end of filename, but leaves the extension asd.txt + "fg" -> asdfg.txt
path& path::append_filename(const string_type& str) {
const auto t = extension().native();
_s.erase(_s.size() - t.size()); // remove extension
_s += str; // append string
_s += t; // add back extension
return *this;
}
path& path::replace_extension(const path& replacement) {
const auto t = extension().native();
_s.erase(_s.size() - t.size());

View File

@ -155,6 +155,8 @@ struct path {
path& replace_extension(const path& replacement = path());
path& append_filename(const string_type& str);
private:
string_type _s;
};

View File

@ -31,6 +31,9 @@ using namespace std::literals;
const std::string_view center_freq_name = "center_frequency"sv;
const std::string_view sample_rate_name = "sample_rate"sv;
const std::string_view latitude_name = "latitude"sv;
const std::string_view longitude_name = "longitude"sv;
const std::string_view satinuse_name = "satinuse"sv;
fs::path get_metadata_path(const fs::path& capture_path) {
auto temp = capture_path;
@ -54,6 +57,23 @@ Optional<File::Error> write_metadata_file(const fs::path& path, capture_metadata
if (error)
return error;
// add gps data if available
if (metadata.latitude != 0 && metadata.longitude != 0 && metadata.latitude < 200 && metadata.longitude < 200) {
error = f.write_line(std::string{latitude_name} + "=" +
to_string_decimal(metadata.latitude, 7));
if (error)
return error;
error = f.write_line(std::string{longitude_name} + "=" +
to_string_decimal(metadata.longitude, 7));
if (error)
return error;
error = f.write_line(std::string{satinuse_name} + "=" +
to_string_dec_uint(metadata.satinuse));
if (error)
return error;
}
return {};
}
@ -77,6 +97,12 @@ Optional<capture_metadata> read_metadata_file(const fs::path& path) {
parse_int(cols[1], metadata.center_frequency);
else if (cols[0] == sample_rate_name)
parse_int(cols[1], metadata.sample_rate);
else if (cols[0] == latitude_name)
parse_float_meta(cols[1], metadata.latitude);
else if (cols[0] == longitude_name)
parse_float_meta(cols[1], metadata.longitude);
else if (cols[0] == satinuse_name)
parse_int(cols[1], metadata.satinuse);
else
continue;
}
@ -86,3 +112,18 @@ Optional<capture_metadata> read_metadata_file(const fs::path& path) {
return metadata;
}
bool parse_float_meta(std::string_view str, float& out_val) {
out_val = {};
if (str.size() > max_parse_int_length)
return false;
// Copy onto the stack and null terminate.
char zstr[max_parse_int_length + 1];
std::memcpy(zstr, str.data(), str.size());
zstr[str.size()] = '\0';
errno = 0;
out_val = strtod(zstr, nullptr);
return (errno == 0);
}

View File

@ -29,6 +29,9 @@
struct capture_metadata {
rf::Frequency center_frequency;
uint32_t sample_rate;
float latitude = 0;
float longitude = 0;
uint8_t satinuse = 0;
};
std::filesystem::path get_metadata_path(const std::filesystem::path& capture_path);
@ -36,4 +39,5 @@ std::filesystem::path get_metadata_path(const std::filesystem::path& capture_pat
Optional<File::Error> write_metadata_file(const std::filesystem::path& path, capture_metadata metadata);
Optional<capture_metadata> read_metadata_file(const std::filesystem::path& path);
bool parse_float_meta(std::string_view str, float& out_val);
#endif // __METADATA_FILE_HPP__

View File

@ -205,6 +205,11 @@ void RecordView::start() {
return;
}
// check for geo data, if present append filename with _GEO
if (latitude != 0 && longitude != 0 && latitude < 200 && longitude < 200) {
base_path.append_filename(u"_GEO");
}
std::unique_ptr<stream::Writer> writer;
switch (file_type) {
case FileType::WAV: {
@ -223,7 +228,7 @@ void RecordView::start() {
case FileType::RawS8:
case FileType::RawS16: {
const auto metadata_file_error = write_metadata_file(
get_metadata_path(base_path), {receiver_model.target_frequency(), sampling_rate});
get_metadata_path(base_path), {receiver_model.target_frequency(), sampling_rate, latitude, longitude, satinuse});
if (metadata_file_error.is_valid()) {
handle_error(metadata_file_error.value());
return;
@ -342,6 +347,12 @@ void RecordView::trim_capture() {
trim_path = {};
}
void RecordView::on_gps(const GPSPosDataMessage* msg) {
latitude = msg->lat;
longitude = msg->lon;
satinuse = msg->satinuse;
}
void RecordView::handle_capture_thread_done(const File::Error error) {
stop();
if (error.code()) {

View File

@ -88,6 +88,7 @@ class RecordView : public View {
OversampleRate get_oversample_rate(uint32_t sample_rate);
void on_gps(const GPSPosDataMessage* msg);
// bool pitch_rssi_enabled = false;
// Time Stamp
@ -95,6 +96,10 @@ class RecordView : public View {
bool filename_as_is = false;
rtc::RTC datetime{};
float latitude = 0; // for wardriwing with ext module
float longitude = 0;
uint8_t satinuse = 0; // to see if there was enough sats used or not
const std::filesystem::path filename_stem_pattern;
const std::filesystem::path folder;
FileType file_type;
@ -147,6 +152,13 @@ class RecordView : public View {
const auto message = *reinterpret_cast<const CaptureThreadDoneMessage*>(p);
this->handle_capture_thread_done(message.error);
}};
MessageHandlerRegistration message_handler_gps{
Message::ID::GPSPosData,
[this](Message* const p) {
const auto message = static_cast<const GPSPosDataMessage*>(p);
this->on_gps(message);
}};
};
} /* namespace ui */

View File

@ -905,8 +905,8 @@ static void cmd_cpld_read(BaseSequentialStream* chp, int argc, char* argv[]) {
}
static void cmd_gotgps(BaseSequentialStream* chp, int argc, char* argv[]) {
const char* usage = "usage: gotgps <lat> <lon> [altitude] [speed]\r\n";
if (argc < 2 || argc > 4) {
const char* usage = "usage: gotgps <lat> <lon> [altitude] [speed] [satinuse]\r\n";
if (argc < 2 || argc > 5) {
chprintf(chp, usage);
return;
}
@ -914,9 +914,11 @@ static void cmd_gotgps(BaseSequentialStream* chp, int argc, char* argv[]) {
float lon = atof(argv[1]);
int32_t altitude = 0;
int32_t speed = 0;
uint8_t satinuse = 0;
if (argc >= 3) altitude = strtol(argv[2], NULL, 10);
if (argc >= 4) speed = strtol(argv[3], NULL, 10);
GPSPosDataMessage msg{lat, lon, altitude, speed};
if (argc >= 5) satinuse = strtol(argv[4], NULL, 10);
GPSPosDataMessage msg{lat, lon, altitude, speed, satinuse};
EventDispatcher::send_message(msg);
chprintf(chp, "ok\r\n");
}

View File

@ -1313,17 +1313,20 @@ class GPSPosDataMessage : public Message {
float lat = 200.0,
float lon = 200.0,
int32_t altitude = 0,
int32_t speed = 0)
int32_t speed = 0,
uint8_t satinuse = 0)
: Message{ID::GPSPosData},
lat{lat},
lon{lon},
altitude{altitude},
speed{speed} {
speed{speed},
satinuse{satinuse} {
}
float lat = 200.0;
float lon = 200.0;
int32_t altitude = 0;
int32_t speed = 0;
uint8_t satinuse = 0;
};
class OrientationDataMessage : public Message {