void igc_step() { char line[79]; uint8_t sec; uint8_t min; uint8_t hour; char c; int16_t galt; DEBUG("igc_step %d %d\n", fc.gps_data.valid, fc.gps_data.fix); if (fc.gps_data.valid && fc.gps_data.fix == 3) { if (fc.logger_state == LOGGER_WAIT_FOR_GPS) fc.logger_state = LOGGER_ACTIVE; if (igc_last_timestamp >= fc.gps_data.utc_time) { // DEBUG("igc_last_timestamp >= fc.gps_data.utc_time\n"); return; } igc_last_timestamp = fc.gps_data.utc_time; time_from_epoch(fc.gps_data.utc_time, &sec, &min, &hour); //New igc specification require altitude above geoid //From L80_GPS_Protocol_Specification_V1.4.pdf //fc.gps_data.altitude - Altitude in meters according to WGS84 ellipsoid //fc.gps_data.geoid - Height of geoid above WGS84 ellipsoid //BUT datasheet is lying !!! fc.gps_data.altitude is MSL !!! galt = fc.gps_data.altitude; c = 'A'; } else { if (fc.logger_state == LOGGER_WAIT_FOR_GPS) return; if (igc_last_timestamp >= time_get_utc()) return; igc_last_timestamp = time_get_utc(); time_from_epoch(time_get_utc(), &sec, &min, &hour); galt = 0; c = 'V'; } uint16_t alt = fc_press_to_alt(fc.vario.pressure, 101325); //B record sprintf_P(line, PSTR("B%02d%02d%02d%s%s%c%05d%05d"), hour, min, sec, fc.gps_data.cache_igc_latitude, fc.gps_data.cache_igc_longtitude, c, alt, galt); igc_writeline(line); igc_write_grecord(); }
uint8_t aero_start(char * path) { char filename[128]; uint8_t sec; uint8_t min; uint8_t hour; uint8_t day; uint8_t wday; uint8_t month; uint16_t year; datetime_from_epoch(time_get_utc(), &sec, &min, &hour, &day, &wday, &month, &year); sprintf_P(filename, PSTR("%sAER"), path); DEBUG("RAW filename %s\n", filename); uint8_t res = f_open(&log_file, filename, FA_WRITE | FA_CREATE_ALWAYS); assert(res == FR_OK); //cannot create file if (res != FR_OK) return false; aero_last_time = 0; return LOGGER_ACTIVE; }
void logger_start() { if (!config.logger.enabled) return; logger_next_flight(); if (!storage_ready()) { gui_showmessage_P(PSTR("SD card error!")); fc.logger_state = LOGGER_ERROR; return; } uint8_t sec; uint8_t min; uint8_t hour; uint8_t day; uint8_t wday; uint8_t month; uint16_t year; datetime_from_epoch(time_get_utc(), &sec, &min, &hour, &day, &wday, &month, &year); char path[128]; //base dir sprintf_P(path, PSTR("%S"), LOG_DIR); f_mkdir(path); //year sprintf_P(path, PSTR("%S/%04d"), LOG_DIR, year); f_mkdir(path); //month sprintf_P(path, PSTR("%S/%04d/%02d"), LOG_DIR, year, month); f_mkdir(path); //day sprintf_P(path, PSTR("%S/%04d/%02d/%02d"), LOG_DIR, year, month, day); f_mkdir(path); switch (config.logger.format) { case(LOGGER_IGC): fc.logger_state = igc_start(path); break; case(LOGGER_KML): fc.logger_state = kml_start(path); break; case(LOGGER_RAW): fc.logger_state = raw_start(path); break; } }
/** * Insert a line into the log containing a XML element and "now" as the content, * e.g. "<end>2016-12-24T18:00:00Z</end>". * * \param tag the name of the XML element, in the above example, this would be "end". */ void kml_now(const char *tag) { uint8_t sec; uint8_t min; uint8_t hour; uint8_t day; uint8_t wday; uint8_t month; uint16_t year; datetime_from_epoch(time_get_utc(), &sec, &min, &hour, &day, &wday, &month, &year); kml_sprintf_P(PSTR("<%s>%04d-%02d-%02dT%02d:%02d:%02dZ</%s>"), tag, year, month, day, hour, min, sec, tag); }
bool kml_start(char * path) { char filename[128]; uint8_t sec; uint8_t min; uint8_t hour; uint8_t day; uint8_t wday; uint8_t month; uint16_t year; char line[79]; char id[32]; datetime_from_epoch(time_get_utc(), &sec, &min, &hour, &day, &wday, &month, &year); sprintf_P(filename, PSTR("/%s/%02d-%02d%02d.KML"), path, logger_flight_number, hour, min); DEBUG("KML filename %s\n", filename); uint8_t res = f_open(log_fil, filename, FA_WRITE | FA_CREATE_ALWAYS); assert(res == FR_OK); //cannot create file if (res != FR_OK) return false; //header GetID_str(id); sprintf_P(line, PSTR("<!-- Generated by SkyDrop vario (www.skybean.eu) -->")); kml_writeline(line); sprintf_P(line, PSTR("<!-- Date: %02d.%02d.%04d -->"), day, month, year); kml_writeline(line); sprintf_P(line, PSTR("<!-- Time: %02d:%02d -->"), hour, min); kml_writeline(line); sprintf_P(line, PSTR("<!-- Pilot: %s -->"), config.logger.pilot); kml_writeline(line); sprintf_P(line, PSTR("<!-- Glider type: %s -->"), config.logger.glider_type); kml_writeline(line); sprintf_P(line, PSTR("<!-- Glider ID: %s -->"), config.logger.glider_id); kml_writeline(line); sprintf_P(line, PSTR("<!-- S/N: %s -->"), id); kml_writeline(line); sprintf_P(line, PSTR("<!-- HW: drop_%d -->"), (hw_revision == HW_REW_1504) ? 1504 : 1506); kml_writeline(line); sprintf_P(line, PSTR("<!-- SW: build %d -->"), BUILD_NUMBER); kml_writeline(line); //body sprintf_P(line, PSTR("<kml xmlns=\"http://earth.google.com/kml/2.0\">")); kml_writeline(line); sprintf_P(line, PSTR("<Document>")); kml_writeline(line); sprintf_P(line, PSTR("<name>Flight log from %02d.%02d.%04d @ %02d:%02d</name>"), day, month, year, hour, min); kml_writeline(line); sprintf_P(line, PSTR("<Placemark>")); kml_writeline(line); sprintf_P(line, PSTR("<name>Flight</name>")); kml_writeline(line); sprintf_P(line, PSTR("<visibility>1</visibility>")); kml_writeline(line); sprintf_P(line, PSTR("<open>1</open>")); kml_writeline(line); sprintf_P(line, PSTR("<Style>")); kml_writeline(line); sprintf_P(line, PSTR("<LineStyle><color>ff00ffff</color></LineStyle>")); kml_writeline(line); sprintf_P(line, PSTR("<PolyStyle><color>7f0000ff</color></PolyStyle>")); kml_writeline(line); sprintf_P(line, PSTR("</Style>")); kml_writeline(line); sprintf_P(line, PSTR("<LineString>")); kml_writeline(line); sprintf_P(line, PSTR("<altitudeMode>absolute</altitudeMode>")); kml_writeline(line); sprintf_P(line, PSTR("<extrude>1</extrude>")); kml_writeline(line); sprintf_P(line, PSTR("<coordinates>")); kml_writeline(line); return (fc.gps_data.valid) ? LOGGER_ACTIVE : LOGGER_WAIT_FOR_GPS; }
uint8_t igc_start(char * path) { char filename[128]; uint8_t sec; uint8_t min; uint8_t hour; uint8_t day; uint8_t wday; uint8_t month; uint16_t year; char line[79]; char id[32]; sha256.init(); IGC_PRIVATE_KEY_ADD; datetime_from_epoch(time_get_utc(), &sec, &min, &hour, &day, &wday, &month, &year); //XXX #define device_uid "DRP" sprintf_P(filename, PSTR("%sIGC"), path); DEBUG("IGC filename %s\n", filename); uint8_t res = f_open(&log_file, filename, FA_WRITE | FA_CREATE_ALWAYS); assert(res == FR_OK); DEBUG("f_open res = %02X\n", res); //cannot create file if (res != FR_OK) return false; //A record GetID_str(id); sprintf_P(line, PSTR("A%S%s:%s"), LOG_MID_P, device_uid, id); igc_writeline(line); //H records //H F DTE sprintf_P(line, PSTR("HFDTE%02u%02u%02u"), day, month, year % 100); igc_writeline(line); // //H F DTE // sprintf_P(line, PSTR("HFDTEDATE:%02u%02u%02u,%02u"), day, month, year % 100, logger_flight_number); // igc_writeline(line); //H F PLT PILOT IN CHARGE sprintf_P(line, PSTR("HFPLTPILOTINCHARGE:%s"), config.logger.pilot); igc_writeline(line); //H F CM2 CREW 2 sprintf_P(line, PSTR("HFCM2CREW2:NIL")); igc_writeline(line); //H F GTY GLIDER TYPE sprintf_P(line, PSTR("HFGTYGLIDERTYPE:%s"), config.logger.glider_type); igc_writeline(line); //H F GID GLIDER ID sprintf_P(line, PSTR("HFGIDGLIDERID:%s"), config.logger.glider_id); igc_writeline(line); //H F DTM GPS DATUM sprintf_P(line, PSTR("HFDTMGPSDATUM:WGS84")); igc_writeline(line); //H F RFW FIRMWARE VERSION sprintf_P(line, PSTR("HFRFWFIRMWAREVERSION:build %d"), BUILD_NUMBER); igc_writeline(line); //H F RHW HARDWARE VERSION sprintf_P(line, PSTR("HFRHWHARDWAREVERSION:drop_%d"), (hw_revision == HW_REW_1504) ? 1504 : 1506); igc_writeline(line); //H F FTY FR TYPE sprintf_P(line, PSTR("HFFTYFRTYPE:SkyBean,SkyDrop")); igc_writeline(line); //H F GPS RECEIVER sprintf_P(line, PSTR("HFGPSRECEIVER:Quectel,L80,22cm,18000m")); igc_writeline(line); //H F PRS PRESS ALT SENSOR sprintf_P(line, PSTR("HFPRSPRESSALTSENSOR:Measurement specialties,MS5611,25907m")); igc_writeline(line); //H F ALG ALT GPS sprintf_P(line, PSTR("HFALGALTGPS:GEO")); igc_writeline(line); //H F ALP sprintf_P(line, PSTR("HFALPALTPRESSURE:ISA")); igc_writeline(line); //H F TZN sprintf_P(line, PSTR("HFTZNTIMEZONE:%+0.1f"), config.system.time_zone / 2.0); igc_writeline(line); #ifdef IGC_NO_PRIVATE_KEY //Developer note: we can't publish the private key for signing the IGC file //H F FRS sprintf_P(line, PSTR("HFFRSSECSUSPECTUSEVALIPROG:This file is not valid. Private key not available!")); igc_writeline(line); #endif //dump the cache // DEBUG("IGC dump len %d\n", igc_pre_start_len); for (uint8_t i = igc_pre_start_len; i > 0; i--) { int8_t index = igc_pre_start_index - i; if (index < 0) index += IGC_PRE_START_BUFFER; // DEBUG("IGC dump %d\n", index); igc_pre_fix * pfix = &igc_pre_start_cache[index]; int16_t galt = pfix->galt; char c = 'A'; if (galt == 0x7FFF) { galt = 0; c = 'V'; } sprintf_P(line, PSTR("B%02d%02d%02d%s%s%c%05d%05d"), pfix->hour, pfix->min, pfix->sec, pfix->cache_igc_latitude, pfix->cache_igc_longtitude, c, pfix->balt, galt); igc_writeline(line); } // igc_comment("End of cache"); igc_write_grecord(); return (fc.gps_data.valid) ? LOGGER_ACTIVE : LOGGER_WAIT_FOR_GPS; }
uint8_t kml_start(char * path) { char filename[128]; uint8_t sec; uint8_t min; uint8_t hour; uint8_t day; uint8_t wday; uint8_t month; uint16_t year; char id[32]; datetime_from_epoch(time_get_utc(), &sec, &min, &hour, &day, &wday, &month, &year); sprintf_P(filename, PSTR("%sKML"), path); DEBUG("KML filename %s\n", filename); uint8_t res = f_open(&log_file, filename, FA_WRITE | FA_CREATE_ALWAYS); assert(res == FR_OK); //cannot create file if (res != FR_OK) return false; //header GetID_str(id); kml_sprintf_P(PSTR("<!-- Generated by SkyDrop vario (www.skybean.eu) -->")); kml_sprintf_P(PSTR("<!-- Date: %02d.%02d.%04d -->"), day, month, year); kml_sprintf_P(PSTR("<!-- Time: %02d:%02d -->"), hour, min); kml_sprintf_P(PSTR("<!-- Pilot: %s -->"), config.logger.pilot); kml_sprintf_P(PSTR("<!-- Glider type: %s -->"), config.logger.glider_type); kml_sprintf_P(PSTR("<!-- Glider ID: %s -->"), config.logger.glider_id); kml_sprintf_P(PSTR("<!-- S/N: %s -->"), id); kml_sprintf_P(PSTR("<!-- HW: drop_%d -->"), (hw_revision == HW_REW_1504) ? 1504 : 1506); kml_sprintf_P(PSTR("<!-- SW: build %d -->"), BUILD_NUMBER); //body kml_sprintf_P(PSTR("<kml xmlns=\"http://www.opengis.net/kml/2.2\">")); kml_sprintf_P(PSTR("<Document>")); kml_sprintf_P(PSTR("<name>Flight log from %02d.%02d.%04d @ %02d:%02d</name>"), day, month, year, hour, min); kml_sprintf_P(PSTR("<Placemark id=\"%s-%ld\">"), id, time_get_utc()); kml_sprintf_P(PSTR("<name>Flight</name>")); kml_sprintf_P(PSTR("<visibility>1</visibility>")); kml_sprintf_P(PSTR("<open>1</open>")); kml_sprintf_P(PSTR("<TimeSpan>")); kml_now("begin"); // Save position of end date, so that we can overwrite on close: filepos_for_end = f_tell(&log_file); kml_now("end"); kml_sprintf_P(PSTR("</TimeSpan>")); kml_sprintf_P(PSTR("<Style>")); kml_sprintf_P(PSTR("<LineStyle><color>ff00ffff</color></LineStyle>")); kml_sprintf_P(PSTR("<PolyStyle><color>7f0000ff</color></PolyStyle>")); kml_sprintf_P(PSTR("</Style>")); kml_sprintf_P(PSTR("<LineString>")); kml_sprintf_P(PSTR("<extrude>1</extrude>")); kml_sprintf_P(PSTR("<altitudeMode>absolute</altitudeMode>")); kml_sprintf_P(PSTR("<coordinates>")); return (fc.gps_data.valid) ? LOGGER_ACTIVE : LOGGER_WAIT_FOR_GPS; }