diff --git a/js/flightlog.js b/js/flightlog.js index 9e8fb994..43423a03 100644 --- a/js/flightlog.js +++ b/js/flightlog.js @@ -207,15 +207,23 @@ function FlightLog(logData) { } else return false; }; - + function buildFieldNames() { // Make an independent copy fieldNames = parser.frameDefs.I.name.slice(0); // Add names of slow fields which we'll merge into the main stream if (parser.frameDefs.S) { - for (let i = 0; i < parser.frameDefs.S.name.length; i++) { - fieldNames.push(parser.frameDefs.S.name[i]); + for (const name of parser.frameDefs.S.name) { + fieldNames.push(name); + } + } + // Add names of gps fields which we'll merge into the main stream + if (parser.frameDefs.G) { + for (const name of parser.frameDefs.G.name) { + if (name !== 'time') { // remove duplicate time field + fieldNames.push(name); + } } } @@ -375,11 +383,14 @@ function FlightLog(logData) { var mainFrameIndex = 0, slowFrameLength = parser.frameDefs.S ? parser.frameDefs.S.count : 0, - lastSlow = parser.frameDefs.S ? iframeDirectory.initialSlow[chunkIndex].slice(0) : []; + lastSlow = parser.frameDefs.S ? iframeDirectory.initialSlow[chunkIndex].slice(0) : [], + lastGPSLength = parser.frameDefs.G ? parser.frameDefs.G.count-1 : 0, // -1 since we exclude the time field + lastGPS = parser.frameDefs.G ? iframeDirectory.initialGPS[chunkIndex].slice(0) : []; parser.onFrameReady = function(frameValid, frame, frameType, frameOffset, frameSize) { var - destFrame; + destFrame, + destFrame_currentIndex; // The G frames need to be processed always. They are "invalid" if not H (Home) has been detected // before, but if not processed the viewer shows cuts and gaps. This happens if the quad takes off before @@ -392,7 +403,7 @@ function FlightLog(logData) { //The parser re-uses the "frame" array so we must copy that data somewhere else var - numOutputFields = frame.length + slowFrameLength + ADDITIONAL_COMPUTED_FIELD_COUNT; + numOutputFields = frame.length + slowFrameLength + lastGPSLength + ADDITIONAL_COMPUTED_FIELD_COUNT; //Do we have a recycled chunk to copy on top of? if (chunk.frames[mainFrameIndex]) { @@ -409,10 +420,18 @@ function FlightLog(logData) { destFrame[i] = frame[i]; } + destFrame_currentIndex = frame.length; // Keeps track of where to place direct data in the destFrame. // Then merge in the last seen slow-frame data - for (var i = 0; i < slowFrameLength; i++) { - destFrame[i + frame.length] = lastSlow[i] === undefined ? null : lastSlow[i]; + for (let slowFrameIndex = 0; slowFrameIndex < slowFrameLength; slowFrameIndex++) { + destFrame[slowFrameIndex + destFrame_currentIndex] = lastSlow[slowFrameIndex] === undefined ? null : lastSlow[slowFrameIndex]; } + destFrame_currentIndex += slowFrameLength; + + // Also merge last seen gps-frame data + for (let gpsFrameIndex = 0; gpsFrameIndex < lastGPSLength; gpsFrameIndex++) { + destFrame[gpsFrameIndex + destFrame_currentIndex] = lastGPS[gpsFrameIndex] === undefined ? null : lastGPS[gpsFrameIndex]; + } + // destFrame_currentIndex += lastGPSLength; Add this line if you wish to add more fields. for (var i = 0; i < eventNeedsTimestamp.length; i++) { eventNeedsTimestamp[i].time = frame[FlightLogParser.prototype.FLIGHT_LOG_FIELD_INDEX_TIME]; @@ -446,10 +465,18 @@ function FlightLog(logData) { } break; case 'H': + // TODO + // contains coordinates only + // should be handled separately case 'G': - // TODO pending to do something with GPS frames // The frameValid can be false, when no GPS home (the G frames contains GPS position as diff of GPS Home position). // But other data from the G frame can be valid (time, num sats) + + //H Field G name:time,GPS_numSat,GPS_coord[0],GPS_coord[1],GPS_altitude,GPS_speed,GPS_ground_course + frame.shift(); // remove time + for (let i = 0; i < frame.length; i++) { + lastGPS[i] = frame[i]; + } break; } } else { diff --git a/js/flightlog_fields_presenter.js b/js/flightlog_fields_presenter.js index 0568cf82..d8011eb5 100644 --- a/js/flightlog_fields_presenter.js +++ b/js/flightlog_fields_presenter.js @@ -106,6 +106,13 @@ function FlightLogFieldPresenter() { 'rxSignalReceived': 'RX Signal Received', 'rxFlightChannelsValid': 'RX Flight Ch. Valid', 'rssi': 'RSSI', + + 'GPS_numSat': "GPS Sat Count", + 'GPS_coord[0]': "GPS Latitude", + 'GPS_coord[1]': "GPS Longitude", + 'GPS_altitude': "GPS Altitude ASL", + 'GPS_speed': "GPS Speed", + 'GPS_ground_course': "GPS Heading", }; const DEBUG_FRIENDLY_FIELD_NAMES_INITIAL = { @@ -977,6 +984,19 @@ function FlightLogFieldPresenter() { case 'rssi': return (value / 1024 * 100).toFixed(2) + " %"; + //H Field G name:time,GPS_numSat,GPS_coord[0],GPS_coord[1],GPS_altitude,GPS_speed,GPS_ground_course + case 'GPS_numSat': + return `${value}`; + case 'GPS_coord[0]': + case 'GPS_coord[1]': + return `${(value/10000000).toFixed(5)}`; + case 'GPS_altitude': + return `${(value/10).toFixed(2)} m`; + case 'GPS_speed': + return `${(value/100).toFixed(2)} m/s`; + case 'GPS_ground_course': + return `${(value/10).toFixed(1)} °`; + case 'debug[0]': case 'debug[1]': case 'debug[2]': diff --git a/js/flightlog_index.js b/js/flightlog_index.js index a6c836da..b42f531e 100644 --- a/js/flightlog_index.js +++ b/js/flightlog_index.js @@ -46,6 +46,7 @@ function FlightLogIndex(logData) { initialIMU: [], initialSlow: [], initialGPSHome: [], + initialGPS: [], hasEvent: [], minTime: false, maxTime: false @@ -77,14 +78,15 @@ function FlightLogIndex(logData) { var sysConfig = parser.sysConfig, mainFrameDef = parser.frameDefs.I, - + gyroADC = [mainFrameDef.nameToIndex["gyroADC[0]"], mainFrameDef.nameToIndex["gyroADC[1]"], mainFrameDef.nameToIndex["gyroADC[2]"]], accSmooth = [mainFrameDef.nameToIndex["accSmooth[0]"], mainFrameDef.nameToIndex["accSmooth[1]"], mainFrameDef.nameToIndex["accSmooth[2]"]], magADC = [mainFrameDef.nameToIndex["magADC[0]"], mainFrameDef.nameToIndex["magADC[1]"], mainFrameDef.nameToIndex["magADC[2]"]], lastSlow = [], - lastGPSHome = []; - + lastGPSHome = [], + lastGPS = []; + // Identify motor fields so they can be used to show the activity summary bar for (var j = 0; j < 8; j++) { if (mainFrameDef.nameToIndex["motor[" + j + "]"] !== undefined) { @@ -139,6 +141,7 @@ function FlightLogIndex(logData) { intraIndex.initialIMU.push(new IMU(imu)); intraIndex.initialSlow.push(lastSlow); intraIndex.initialGPSHome.push(lastGPSHome); + intraIndex.initialGPS.push(lastGPS); } iframeCount++; @@ -153,6 +156,10 @@ function FlightLogIndex(logData) { magADC ? [frame[magADC[0]], frame[magADC[1]], frame[magADC[2]]] : false ); break; + case 'G': + lastGPS = frame.slice(0); + lastGPS.shift(); // Remove the time field + break; case 'H': lastGPSHome = frame.slice(0); break; diff --git a/js/graph_config.js b/js/graph_config.js index c155a920..9e28e965 100644 --- a/js/graph_config.js +++ b/js/graph_config.js @@ -353,6 +353,27 @@ GraphConfig.load = function(config) { inputRange: 512, outputRange: 1.0 }; + } else if (fieldName == 'GPS_ground_course') { + return { + offset: -1800, + power: 1.0, + inputRange: 1800, + outputRange: 1.0 + }; + } else if (fieldName == 'GPS_numSat') { + return { + offset: -20, + power: 1.0, + inputRange: 20, + outputRange: 1.0 + }; + } else if (fieldName == 'GPS_speed') { + return { + offset: 0, + power: 1.0, + inputRange: 1000, + outputRange: 1.0 + }; } else if (fieldName.match(/^debug.*/) && sysConfig.debug_mode!=null) { var debugModeName = DEBUG_MODE[sysConfig.debug_mode]; @@ -956,6 +977,10 @@ GraphConfig.load = function(config) { EXAMPLE_GRAPHS.push({label: "Debug",fields: ["debug[all]"]}); } + if (!flightLog.isFieldDisabled().GPS) { + EXAMPLE_GRAPHS.push({label: "GPS",fields: ["GPS_numSat", "GPS_altitude", "GPS_speed", "GPS_ground_course", "GPS_coord[all]"]}); + } + for (i = 0; i < EXAMPLE_GRAPHS.length; i++) { var srcGraph = EXAMPLE_GRAPHS[i], diff --git a/js/main.js b/js/main.js index 48aae6ba..17f86e7b 100644 --- a/js/main.js +++ b/js/main.js @@ -166,7 +166,7 @@ function BlackboxLogViewer() { if (value === null) return "(absent)"; - + return value.toFixed(2); }