diff --git a/auto_rx/autorx/aprs.py b/auto_rx/autorx/aprs.py index e4551a4..9627d66 100644 --- a/auto_rx/autorx/aprs.py +++ b/auto_rx/autorx/aprs.py @@ -49,7 +49,7 @@ def telemetry_to_aprs_position(sonde_data, object_name="", aprs_comment="BOM _object_name = "DF6" + _id_suffix elif 'M10' in sonde_data['type']: # Use the generated id same as dxlARPS - _object_name = sonde_data['id'] + _object_name = sonde_data['dxlid'] # New Sonde types will be added in here. else: # Unknown sonde type, don't know how to handle this yet. diff --git a/m10/M10.cpp b/m10/M10.cpp index ec6348b..8e7f400 100644 --- a/m10/M10.cpp +++ b/m10/M10.cpp @@ -27,7 +27,9 @@ int main(int argc, char** argv) { fprintf(stderr, " options:\n"); fprintf(stderr, " -v, --verbose Display even when CRC is wrong\n"); fprintf(stderr, " -R Show result at the end decoded/total\n"); + fprintf(stderr, " -r Display raw information\n"); fprintf(stderr, " -b Try alternative method after main method if it failed\n"); + fprintf(stderr, " -b2 Try to repair data with the previous line\n"); fprintf(stderr, " --ch2 Decode the second channel\n"); return 0; @@ -37,6 +39,8 @@ int main(int argc, char** argv) { decoder.setVerboseLevel(1); } else if (strcmp(*argv, "-b") == 0) { decoder.setTryMethodSign(true); + } else if (strcmp(*argv, "-b2") == 0) { + decoder.setTryMethodRepair(true); } else if (strcmp(*argv, "-R") == 0) { decoder.setDispResult(true); } else if (strcmp(*argv, "--ch2") == 0) { diff --git a/m10/M10Decoder.cpp b/m10/M10Decoder.cpp index 50b25ac..b9e4b11 100644 --- a/m10/M10Decoder.cpp +++ b/m10/M10Decoder.cpp @@ -56,7 +56,6 @@ int M10Decoder::startDecode(std::string fname) { c++; if (decodeMessage(res) == EOF_INT) break; - bits2bytes(); long sondeType = ((long) frame_bytes[0] << 16) + ((long) frame_bytes[1] << 8) + (long) frame_bytes[2]; supported = true; @@ -77,10 +76,16 @@ int M10Decoder::startDecode(std::string fname) { fprintf(stderr, "Not supported : %#06x\n", (unsigned int) sondeType); continue; } - if (correctCRC) + if (correctCRC) { correct++; + lastGoodFrame = frame_bytes; + } + m10Parser->changeData(frame_bytes, correctCRC); m10Parser->printFrame(); + + if (!correctCRC && tryRepair) + m10Parser->changeData(lastGoodFrame, true); } } if (dispResult) @@ -198,6 +203,12 @@ int M10Decoder::decodeMessage(double initialPos) { if (ret == EOF_INT) return EOF_INT; + if (tryRepair) { + frame_bytes = m10Parser->replaceWithPrevious(frame_bytes); + if (checkCRC()) + return 0; + } + if (trySign) { // Reset the index curIndex = 0; @@ -206,9 +217,15 @@ int M10Decoder::decodeMessage(double initialPos) { return 0; if (ret == EOF_INT) return EOF_INT; + + if (tryRepair) { + frame_bytes = m10Parser->replaceWithPrevious(frame_bytes); + if (checkCRC()) + return 0; + } } - return 0; + return 1; } int M10Decoder::decodeMethodCompare(double initialPos) { @@ -273,6 +290,7 @@ int M10Decoder::decodeMethodCompare(double initialPos) { bit0 = 1; } } + bits2bytes(); return !checkCRC(); } @@ -340,9 +358,16 @@ int M10Decoder::decodeMethodSign(double initialPos) { bit0 = 1; } } + bits2bytes(); return !checkCRC(); } +void M10Decoder::setRaw(bool b) { + dispRaw = b; + m10GTop->setRaw(b); + m10Ptu->setRaw(b); +} + int M10Decoder::read_wav_header() { char txt[4 + 1] = "\0\0\0\0"; unsigned char dat[4]; diff --git a/m10/M10Decoder.h b/m10/M10Decoder.h index dd97ddb..35f9916 100644 --- a/m10/M10Decoder.h +++ b/m10/M10Decoder.h @@ -32,10 +32,11 @@ public: virtual double findFrameStart(); virtual int decodeMessage(double initialPos); - void setRaw(bool b) {dispRaw = b;} + void setRaw(bool b); void setDispResult(bool b) {dispResult = b;} void setChannel(int c) {targetedChannel = c;} void setTryMethodSign(bool b) {trySign = b;} + void setTryMethodRepair(bool b) {tryRepair = b;} void setVerboseLevel(int level) {verboseLevel = level;} private: int decodeMethodCompare(double initialPos); @@ -55,6 +56,7 @@ private: bool dispResult = false; bool dispRaw = false; bool trySign = false; + bool tryRepair = false; int verboseLevel = 0; int targetedChannel = 0; int sample_rate = 0; @@ -72,6 +74,7 @@ private: std::array frame_bytes; std::array frame_bits; + std::array lastGoodFrame; }; #endif /* M10DECODER_H */ diff --git a/m10/M10GTopParser.cpp b/m10/M10GTopParser.cpp index 1d6faa6..59f5988 100644 --- a/m10/M10GTopParser.cpp +++ b/m10/M10GTopParser.cpp @@ -179,27 +179,39 @@ std::string M10GTopParser::getSerialNumber() { int i; unsigned byte; unsigned short sn_bytes[5]; - //char SN[12]; + char SN[12]; - /*for (i = 0; i < 11; i++) + for (i = 0; i < 11; i++) SN[i] = ' '; - SN[11] = '\0';*/ + SN[11] = '\0'; for (i = 0; i < 5; i++) { byte = frame_bytes[0x5D + i]; sn_bytes[i] = byte; } - // More meaningfull way - /*byte = sn_bytes[2]; + byte = sn_bytes[2]; sprintf(SN, "%1X%02u", (byte >> 4)&0xF, byte & 0xF); byte = sn_bytes[3] | (sn_bytes[4] << 8); - sprintf(SN + 3, " %1X %1u%04u", sn_bytes[0]&0xF, (byte >> 13)&0x7, byte & 0x1FFF);*/ + sprintf(SN + 3, " %1X %1u%04u", sn_bytes[0]&0xF, (byte >> 13)&0x7, byte & 0x1FFF); + + return SN; +} + +std::string M10GTopParser::getdxlSerialNumber() { + int i; + unsigned byte; + unsigned short sn_bytes[5]; + + for (i = 0; i < 5; i++) { + byte = frame_bytes[0x5D + i]; + sn_bytes[i] = byte; + } // The way used by dxlARPS used for compatibility. uint32_t id; char ids[9]; - + id = (uint32_t) (((uint32_t) ((uint32_t) (uint8_t) sn_bytes[4] + 256UL * (uint32_t) (uint8_t) sn_bytes[3] + 65536UL * (uint32_t) (uint8_t) @@ -223,34 +235,46 @@ std::string M10GTopParser::getSerialNumber() { } void M10GTopParser::printFrame() { - setenv("TZ", "", 1); // Set local timezone to UTC - time_t frame = 0; - struct tm timeinfo; + if (dispRaw) { + for (int i = 0; i < FRAME_LEN; ++i) { + printf("%02X", frame_bytes[i]); + } + if (correctCRC) + printf(" [OK]"); + else + printf(" [NO]"); + printf("\n"); + } else { + setenv("TZ", "", 1); // Set local timezone to UTC + time_t frame = 0; + struct tm timeinfo; - timeinfo.tm_hour = getHours(); - timeinfo.tm_min = getMinutes(); - timeinfo.tm_sec = getSeconds(); - timeinfo.tm_mday = getDay(); - timeinfo.tm_mon = getMonth() - 1; - timeinfo.tm_year = getYear() - 1900; - timeinfo.tm_isdst = 0; + timeinfo.tm_hour = getHours(); + timeinfo.tm_min = getMinutes(); + timeinfo.tm_sec = getSeconds(); + timeinfo.tm_mday = getDay(); + timeinfo.tm_mon = getMonth() - 1; + timeinfo.tm_year = getYear() - 1900; + timeinfo.tm_isdst = 0; - frame = mktime(&timeinfo); - - printf("{ " - "\"sub_type\": \"%s\", " - "\"frame\": %ld, " - "\"id\": \"%s\", " - "\"datetime\": \"%04d-%02d-%02dT%02d:%02d:%02dZ\", " - "\"lat\": %.5f, " - "\"lon\": %.5f, " - "\"alt\": %.2f, " - "\"vel_h\": %.5f, " - "\"heading\": %.5f, " - "\"vel_v\": %.2f, " - //"\"temp\": %.1f " - "\"crc\": %d " - "}\n", - "GTop", frame, getSerialNumber().c_str(), getYear(), getMonth(), getDay(), getHours(), getMinutes(), getSeconds(), getLatitude(), getLongitude(), - getAltitude(), getHorizontalSpeed(), getDirection(), getVerticalSpeed()/*, getTemperature()*/, correctCRC); + frame = mktime(&timeinfo); + + printf("{ " + "\"sub_type\": \"%s\", " + "\"frame\": %ld, " + "\"id\": \"%s\", " + "\"dxlid\": \"%s\", " + "\"datetime\": \"%04d-%02d-%02dT%02d:%02d:%02dZ\", " + "\"lat\": %.5f, " + "\"lon\": %.5f, " + "\"alt\": %.2f, " + "\"vel_h\": %.5f, " + "\"heading\": %.5f, " + "\"vel_v\": %.2f, " + //"\"temp\": %.1f " + "\"crc\": %d " + "}\n", + "GTop", frame, getSerialNumber().c_str(), getdxlSerialNumber().c_str(), getYear(), getMonth(), getDay(), getHours(), getMinutes(), getSeconds(), getLatitude(), getLongitude(), + getAltitude(), getHorizontalSpeed(), getDirection(), getVerticalSpeed()/*, getTemperature()*/, correctCRC); + } } diff --git a/m10/M10GTopParser.h b/m10/M10GTopParser.h index 83bfd60..9004706 100644 --- a/m10/M10GTopParser.h +++ b/m10/M10GTopParser.h @@ -35,6 +35,7 @@ public: virtual double getHumidity(); virtual double getDp(); virtual std::string getSerialNumber(); + virtual std::string getdxlSerialNumber(); void printFrame(); private: diff --git a/m10/M10GeneralParser.cpp b/m10/M10GeneralParser.cpp index e986c54..00974e2 100644 --- a/m10/M10GeneralParser.cpp +++ b/m10/M10GeneralParser.cpp @@ -70,5 +70,8 @@ std::string M10GeneralParser::getSerialNumber() { return ""; } +std::array M10GeneralParser::replaceWithPrevious(std::array data) { + return data; +} diff --git a/m10/M10GeneralParser.h b/m10/M10GeneralParser.h index 92bc08f..55fa4df 100644 --- a/m10/M10GeneralParser.h +++ b/m10/M10GeneralParser.h @@ -18,6 +18,7 @@ public: M10GeneralParser(); virtual ~M10GeneralParser(); virtual void changeData(std::array data, bool good); + void setRaw(bool b) {dispRaw = b;} virtual double getLatitude(); virtual double getLongitude(); virtual double getAltitude(); @@ -31,11 +32,15 @@ public: virtual double getHorizontalSpeed(); virtual double getDirection(); virtual std::string getSerialNumber(); + std::array getFrameBytes() {return frame_bytes;} + + virtual std::array replaceWithPrevious(std::array data); virtual void printFrame() = 0; protected: std::array frame_bytes; bool correctCRC; + bool dispRaw = false; }; #endif /* M10GENERALDECODER_H */ diff --git a/m10/M10PtuParser.cpp b/m10/M10PtuParser.cpp index 355ef18..677ebe7 100644 --- a/m10/M10PtuParser.cpp +++ b/m10/M10PtuParser.cpp @@ -21,6 +21,9 @@ #include "M10PtuParser.h" +char M10PtuParser::similarData[] = "xxxx----------------------xxxxxxxxxxxxxxxxxxxxxxxxxxx---xxxxxxx--xxxx-----xx----xxxxx------xxxxxxx---"; +char M10PtuParser::insertSpaces[] = "---xx-x-x-x---x---x---x---x-----x-x-----------x---x--x--x-----xx-x-x-x-xx-x-x-x-x----x---x-x-x----xx-"; + M10PtuParser::M10PtuParser() { } @@ -295,27 +298,39 @@ std::string M10PtuParser::getSerialNumber() { int i; unsigned byte; unsigned short sn_bytes[5]; - //char SN[12]; + char SN[12]; - /*for (i = 0; i < 11; i++) + for (i = 0; i < 11; i++) SN[i] = ' '; - SN[11] = '\0';*/ + SN[11] = '\0'; for (i = 0; i < 5; i++) { byte = frame_bytes[0x5D + i]; sn_bytes[i] = byte; } - // More meaningfull way - /*byte = sn_bytes[2]; + byte = sn_bytes[2]; sprintf(SN, "%1X%02u", (byte >> 4)&0xF, byte & 0xF); byte = sn_bytes[3] | (sn_bytes[4] << 8); - sprintf(SN + 3, " %1X %1u%04u", sn_bytes[0]&0xF, (byte >> 13)&0x7, byte & 0x1FFF);*/ + sprintf(SN + 3, " %1X %1u%04u", sn_bytes[0]&0xF, (byte >> 13)&0x7, byte & 0x1FFF); + + return SN; +} + +std::string M10PtuParser::getdxlSerialNumber() { + int i; + unsigned byte; + unsigned short sn_bytes[5]; + + for (i = 0; i < 5; i++) { + byte = frame_bytes[0x5D + i]; + sn_bytes[i] = byte; + } // The way used by dxlARPS used for compatibility. uint32_t id; char ids[9]; - + id = (uint32_t) (((uint32_t) ((uint32_t) (uint8_t) sn_bytes[4] + 256UL * (uint32_t) (uint8_t) sn_bytes[3] + 65536UL * (uint32_t) (uint8_t) @@ -338,38 +353,63 @@ std::string M10PtuParser::getSerialNumber() { return ids; } +std::array M10PtuParser::replaceWithPrevious(std::array data) { + for (int i = 0; i < FRAME_LEN; ++i) { + if (similarData[i] == 'x') { + if(data[i] != frame_bytes[i]) + data[i] = frame_bytes[i]; + data[i] = frame_bytes[i]; + } + } + return data; +} + void M10PtuParser::printFrame() { - setenv("TZ", "", 1); // Set local timezone to UTC - time_t frame = 0; - struct tm timeinfo; + if (dispRaw) { + for (int i = 0; i < FRAME_LEN; ++i) { + if (insertSpaces[i] == 'x') + printf(" "); + printf("%02X", frame_bytes[i]); + } + if (correctCRC) + printf(" [OK]"); + else + printf(" [NO]"); + printf("\n"); + } else { + setenv("TZ", "", 1); // Set local timezone to UTC + time_t frame = 0; + struct tm timeinfo; - timeinfo.tm_hour = getHours(); - timeinfo.tm_min = getMinutes(); - timeinfo.tm_sec = getSeconds(); - timeinfo.tm_mday = getDay(); - timeinfo.tm_mon = getMonth() - 1; - timeinfo.tm_year = getYear() - 1900; - timeinfo.tm_isdst = 0; + timeinfo.tm_hour = getHours(); + timeinfo.tm_min = getMinutes(); + timeinfo.tm_sec = getSeconds(); + timeinfo.tm_mday = getDay(); + timeinfo.tm_mon = getMonth() - 1; + timeinfo.tm_year = getYear() - 1900; + timeinfo.tm_isdst = 0; - frame = mktime(&timeinfo); + frame = mktime(&timeinfo); - // Decoder sensible to comma at the end, strict json - printf("{ " - "\"sub_type\": \"%s\", " - "\"frame\": %ld, " - "\"id\": \"%s\", " - "\"datetime\": \"%04d-%02d-%02dT%02d:%02d:%02dZ\", " - "\"lat\": %.5f, " - "\"lon\": %.5f, " - "\"alt\": %.2f, " - "\"vel_h\": %.5f, " - "\"heading\": %.5f, " - "\"vel_v\": %.2f, " - "\"temp\": %.1f, " - "\"crc\": %d " - "}\n", - "Ptu", frame, getSerialNumber().c_str(), getYear(), getMonth(), getDay(), getHours(), getMinutes(), getSeconds(), getLatitude(), getLongitude(), - getAltitude(), getHorizontalSpeed(), getDirection(), getVerticalSpeed(), getTemperature(), correctCRC); + // Decoder sensible to comma at the end, strict json + printf("{ " + "\"sub_type\": \"%s\", " + "\"frame\": %ld, " + "\"id\": \"%s\", " + "\"dxlid\": \"%s\", " + "\"datetime\": \"%04d-%02d-%02dT%02d:%02d:%02dZ\", " + "\"lat\": %.5f, " + "\"lon\": %.5f, " + "\"alt\": %.2f, " + "\"vel_h\": %.5f, " + "\"heading\": %.5f, " + "\"vel_v\": %.2f, " + "\"temp\": %.1f, " + "\"crc\": %d " + "}\n", + "Ptu", frame, getSerialNumber().c_str(), getdxlSerialNumber().c_str(), getYear(), getMonth(), getDay(), getHours(), getMinutes(), getSeconds(), getLatitude(), getLongitude(), + getAltitude(), getHorizontalSpeed(), getDirection(), getVerticalSpeed(), getTemperature(), correctCRC); + } } /* diff --git a/m10/M10PtuParser.h b/m10/M10PtuParser.h index c74375f..d4f2eed 100644 --- a/m10/M10PtuParser.h +++ b/m10/M10PtuParser.h @@ -35,16 +35,22 @@ public: virtual double getHumidity(); virtual double getDp(); virtual std::string getSerialNumber(); + virtual std::string getdxlSerialNumber(); + + virtual std::array replaceWithPrevious(std::array data); void printFrame(); private: void gps2Date(long GpsWeek, long GpsSeconds, int *Year, int *Month, int *Day); + std::array frameSpaces; int week; int time; int year; int month; int day; + static char similarData[]; + static char insertSpaces[]; }; #endif /* M10GTOP_H */