Unverified Commit f7447639 authored by Don Gagne's avatar Don Gagne Committed by GitHub

Merge pull request #7493 from DonLakeFlyer/LogReplay

Log replay: Fix log file reading
parents 0bab1096 98d4c852
...@@ -215,7 +215,9 @@ quint64 LogReplayLink::_seekToNextMavlinkMessage(mavlink_message_t* nextMsg) ...@@ -215,7 +215,9 @@ quint64 LogReplayLink::_seekToNextMavlinkMessage(mavlink_message_t* nextMsg)
mavlink_status_t status; mavlink_status_t status;
qint64 messageStartPos = -1; qint64 messageStartPos = -1;
while (_logFile.getChar(&nextByte)) { // Loop over every byte mavlink_reset_channel_status(_mavlinkChannel);
while (_logFile.getChar(&nextByte)) {
bool messageFound = mavlink_parse_char(_mavlinkChannel, nextByte, nextMsg, &status); bool messageFound = mavlink_parse_char(_mavlinkChannel, nextByte, nextMsg, &status);
if (status.parse_state == MAVLINK_PARSE_STATE_GOT_STX) { if (status.parse_state == MAVLINK_PARSE_STATE_GOT_STX) {
...@@ -235,6 +237,31 @@ quint64 LogReplayLink::_seekToNextMavlinkMessage(mavlink_message_t* nextMsg) ...@@ -235,6 +237,31 @@ quint64 LogReplayLink::_seekToNextMavlinkMessage(mavlink_message_t* nextMsg)
return 0; return 0;
} }
quint64 LogReplayLink::_findLastTimestamp(void)
{
char nextByte;
mavlink_status_t status;
quint64 lastTimestamp = 0;
mavlink_message_t msg;
// We read through the entire file looking for the last good timestamp. This can be somewhat slow, but trying to work from the
// end of the file can be way slower due to all the seeking back and forth required. So instead we take the simple reliable approach.
_logFile.reset();
mavlink_reset_channel_status(_mavlinkChannel);
while (_logFile.bytesAvailable() > cbTimestamp) {
lastTimestamp = _parseTimestamp(_logFile.read(cbTimestamp));
bool endOfMessage = false;
while (!endOfMessage && _logFile.getChar(&nextByte)) {
endOfMessage = mavlink_parse_char(_mavlinkChannel, nextByte, &msg, &status);
}
}
return lastTimestamp;
}
bool LogReplayLink::_loadLogFile(void) bool LogReplayLink::_loadLogFile(void)
{ {
QString errorMsg; QString errorMsg;
...@@ -258,28 +285,11 @@ bool LogReplayLink::_loadLogFile(void) ...@@ -258,28 +285,11 @@ bool LogReplayLink::_loadLogFile(void)
_logTimestamped = logFilename.endsWith(".tlog"); _logTimestamped = logFilename.endsWith(".tlog");
if (_logTimestamped) { if (_logTimestamped) {
// Get the first timestamp from the log quint64 startTimeUSecs = _parseTimestamp(_logFile.read(cbTimestamp));
// This should be a big-endian uint64. quint64 endTimeUSecs = _findLastTimestamp();
QByteArray timestamp = _logFile.read(cbTimestamp);
quint64 startTimeUSecs = _parseTimestamp(timestamp);
// Now find the last timestamp by scanning for the last MAVLink packet and
// find the timestamp before it. To do this we start searchin a little before
// the end of the file, specifically the maximum MAVLink packet size + the
// timestamp size. This guarantees that we will hit a MAVLink packet before
// the end of the file. Unfortunately, it basically guarantees that we will
// hit more than one. This is why we have to search for a bit.
qint64 fileLoc = _logFile.size() - ((MAVLINK_MAX_PACKET_LEN - cbTimestamp) * 2);
_logFile.seek(fileLoc);
quint64 endTimeUSecs = startTimeUSecs; // Set a sane default for the endtime
mavlink_message_t msg;
quint64 messageTimeUSecs;
while ((messageTimeUSecs = _seekToNextMavlinkMessage(&msg)) > endTimeUSecs) {
endTimeUSecs = messageTimeUSecs;
}
if (endTimeUSecs == startTimeUSecs) { if (endTimeUSecs <= startTimeUSecs) {
errorMsg = tr("The log file '%1' is corrupt. No valid timestamps were found at the end of the file.").arg(logFilename); errorMsg = tr("The log file '%1' is corrupt or empty.").arg(logFilename);
goto Error; goto Error;
} }
......
...@@ -115,6 +115,7 @@ private: ...@@ -115,6 +115,7 @@ private:
void _replayError(const QString& errorMsg); void _replayError(const QString& errorMsg);
quint64 _parseTimestamp(const QByteArray& bytes); quint64 _parseTimestamp(const QByteArray& bytes);
quint64 _seekToNextMavlinkMessage(mavlink_message_t* nextMsg); quint64 _seekToNextMavlinkMessage(mavlink_message_t* nextMsg);
quint64 _findLastTimestamp(void);
quint64 _readNextMavlinkMessage(QByteArray& bytes); quint64 _readNextMavlinkMessage(QByteArray& bytes);
bool _loadLogFile(void); bool _loadLogFile(void);
void _finishPlayback(void); void _finishPlayback(void);
...@@ -131,7 +132,7 @@ private: ...@@ -131,7 +132,7 @@ private:
LogReplayLinkConfiguration* _logReplayConfig; LogReplayLinkConfiguration* _logReplayConfig;
bool _connected; bool _connected;
int _mavlinkChannel; uint8_t _mavlinkChannel;
QTimer _readTickTimer; ///< Timer which signals a read of next log record QTimer _readTickTimer; ///< Timer which signals a read of next log record
QString _errorTitle; ///< Title for communicatorError signals QString _errorTitle; ///< Title for communicatorError signals
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment