2014-05-22 10:13:16 +00:00
|
|
|
function tab_initialize_logging() {
|
|
|
|
ga_tracker.sendAppView('Logging');
|
|
|
|
GUI.active_tab = 'logging';
|
|
|
|
|
2014-05-22 14:06:49 +00:00
|
|
|
var requested_properties = [];
|
|
|
|
|
2014-05-22 10:13:16 +00:00
|
|
|
$('#content').load("./tabs/logging.html", process_html);
|
|
|
|
|
|
|
|
function process_html() {
|
|
|
|
// translate to user-selected language
|
|
|
|
localize();
|
|
|
|
|
|
|
|
// UI hooks
|
|
|
|
$('a.log_file').click(prepare_file);
|
|
|
|
|
|
|
|
$('a.logging').click(function() {
|
|
|
|
if (fileEntry.isFile) {
|
2014-05-22 14:06:49 +00:00
|
|
|
var clicks = $(this).data('clicks');
|
|
|
|
|
|
|
|
if (!clicks) {
|
|
|
|
// reset some variables before start
|
|
|
|
samples = 0;
|
|
|
|
log_buffer = [];
|
|
|
|
requested_properties = [];
|
|
|
|
|
|
|
|
$('.properties input:checked').each(function() {
|
|
|
|
requested_properties.push($(this).prop('name'));
|
|
|
|
});
|
|
|
|
|
|
|
|
if (requested_properties.length) {
|
|
|
|
function poll_data() {
|
|
|
|
// save current
|
|
|
|
crunch_data();
|
|
|
|
|
|
|
|
// request new
|
|
|
|
for (var i = 0; i < requested_properties.length; i++) {
|
|
|
|
send_message(MSP_codes[requested_properties[i]]);
|
|
|
|
|
|
|
|
/* this approach could be used if we want to utilize request time compensation
|
|
|
|
if (i < requested_properties.length -1) {
|
|
|
|
send_message(requested_properties[i]);
|
|
|
|
} else {
|
|
|
|
send_message(requested_properties[i], false, false, poll_data);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-22 14:29:38 +00:00
|
|
|
GUI.interval_add('log_data_pull', poll_data, parseInt($('select.speed').val()), true); // refresh rate goes here
|
2014-05-22 14:06:49 +00:00
|
|
|
GUI.interval_add('flush_data', function() {
|
2014-05-22 14:29:38 +00:00
|
|
|
if (log_buffer.length) { // only execute when there is actual data to write
|
|
|
|
if (fileWriter.readyState == 0 || fileWriter.readyState == 2) {
|
|
|
|
append_to_file(log_buffer.join('\n'));
|
2014-05-22 14:06:49 +00:00
|
|
|
|
2014-05-22 14:29:38 +00:00
|
|
|
$('.samples').text(samples += log_buffer.length);
|
2014-05-22 14:42:34 +00:00
|
|
|
$('.size').text(chrome.i18n.getMessage('loggingKB', [(fileWriter.length / 1024).toFixed(2)]));
|
2014-05-22 14:06:49 +00:00
|
|
|
|
2014-05-22 14:29:38 +00:00
|
|
|
log_buffer = [];
|
|
|
|
} else {
|
|
|
|
console.log('IO having trouble keeping up with the data flow');
|
|
|
|
}
|
2014-05-22 14:06:49 +00:00
|
|
|
}
|
|
|
|
}, 1000);
|
|
|
|
|
2014-05-22 14:29:38 +00:00
|
|
|
$('.speed').prop('disabled', true);
|
2014-05-22 14:42:34 +00:00
|
|
|
$(this).text(chrome.i18n.getMessage('loggingStop'));
|
2014-05-22 14:06:49 +00:00
|
|
|
$(this).data("clicks", !clicks);
|
|
|
|
} else {
|
2014-05-22 14:42:34 +00:00
|
|
|
GUI.log(chrome.i18n.getMessage('loggingErrorOneProperty'));
|
2014-05-22 14:06:49 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
GUI.interval_remove('log_data_pull');
|
|
|
|
GUI.interval_remove('flush_data');
|
|
|
|
|
2014-05-22 14:29:38 +00:00
|
|
|
$('.speed').prop('disabled', false);
|
2014-05-22 14:42:34 +00:00
|
|
|
$(this).text(chrome.i18n.getMessage('loggingStart'));
|
2014-05-22 14:06:49 +00:00
|
|
|
$(this).data("clicks", !clicks);
|
|
|
|
}
|
|
|
|
} else {
|
2014-05-22 14:42:34 +00:00
|
|
|
GUI.log(chrome.i18n.getMessage('loggingErrorLogFile'));
|
2014-05-22 10:13:16 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-05-22 14:06:49 +00:00
|
|
|
var samples = 0;
|
|
|
|
var log_buffer = [];
|
|
|
|
function crunch_data() {
|
|
|
|
var sample = millitime();
|
|
|
|
|
|
|
|
for (var i = 0; i < requested_properties.length; i++) {
|
|
|
|
switch (requested_properties[i]) {
|
|
|
|
case 'MSP_RAW_IMU':
|
|
|
|
sample += ',' + SENSOR_DATA.gyroscope;
|
|
|
|
sample += ',' + SENSOR_DATA.accelerometer;
|
|
|
|
sample += ',' + SENSOR_DATA.magnetometer;
|
|
|
|
break;
|
|
|
|
case 'MSP_ATTITUDE':
|
|
|
|
sample += ',' + SENSOR_DATA.kinematicsX;
|
|
|
|
sample += ',' + SENSOR_DATA.kinematicsY;
|
|
|
|
sample += ',' + SENSOR_DATA.kinematicsZ;
|
|
|
|
break;
|
|
|
|
case 'MSP_ALTITUDE':
|
|
|
|
sample += ',' + SENSOR_DATA.altitude;
|
|
|
|
break;
|
|
|
|
case 'MSP_RC':
|
|
|
|
for (var chan = 0; chan < RC.active_channels; chan++) {
|
|
|
|
sample += ',' + RC.channels[chan];
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'MSP_MOTOR':
|
|
|
|
sample += ',' + MOTOR_DATA;
|
|
|
|
break;
|
|
|
|
case 'MSP_DEBUG':
|
|
|
|
sample += ',' + SENSOR_DATA.debug;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
log_buffer.push(sample);
|
|
|
|
}
|
|
|
|
|
2014-05-22 10:13:16 +00:00
|
|
|
// IO related methods
|
|
|
|
var fileEntry = null;
|
|
|
|
var fileWriter = null;
|
|
|
|
|
|
|
|
function prepare_file() {
|
|
|
|
// create or load the file
|
|
|
|
chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: 'bf_data_log', accepts: [{extensions: ['csv']}]}, function(entry) {
|
|
|
|
if (!entry) {
|
|
|
|
console.log('No file selected');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
fileEntry = entry;
|
|
|
|
|
|
|
|
// echo/console log path specified
|
|
|
|
chrome.fileSystem.getDisplayPath(fileEntry, function(path) {
|
|
|
|
console.log('Log file path: ' + path);
|
|
|
|
});
|
|
|
|
|
|
|
|
// change file entry from read only to read/write
|
|
|
|
chrome.fileSystem.getWritableEntry(fileEntry, function(fileEntryWritable) {
|
|
|
|
// check if file is writable
|
|
|
|
chrome.fileSystem.isWritableEntry(fileEntryWritable, function(isWritable) {
|
|
|
|
if (isWritable) {
|
|
|
|
fileEntry = fileEntryWritable;
|
|
|
|
|
|
|
|
prepare_writer();
|
|
|
|
} else {
|
|
|
|
console.log('File appears to be read only, sorry.');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function prepare_writer() {
|
|
|
|
fileEntry.createWriter(function(writer) {
|
|
|
|
fileWriter = writer;
|
|
|
|
|
|
|
|
fileWriter.onerror = function(e) {
|
|
|
|
console.error(e);
|
|
|
|
};
|
|
|
|
|
|
|
|
fileWriter.onwriteend = function() {
|
|
|
|
// console.log('Data written');
|
|
|
|
};
|
|
|
|
}, function(e) {
|
|
|
|
console.error(e);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function append_to_file(data) {
|
|
|
|
if (fileWriter.position < fileWriter.length) {
|
|
|
|
fileWriter.seek(fileWriter.length);
|
|
|
|
}
|
|
|
|
|
|
|
|
fileWriter.write(new Blob([data + '\n'], {type: 'text/plain'}));
|
|
|
|
}
|
|
|
|
}
|