Commit 5dc78a30 authored by Oleg Dzhimiev's avatar Oleg Dzhimiev

read imu log interface

parent 9a7461bc
......@@ -14,6 +14,7 @@ SRCS = nmea2exif.c log_imu.c
OBJS = nmea2exif.o
PHPSCRIPTS= start_gps_compass.php
PHPWEB= logger_launcher.php imu_setup.php read_imu_log.php
WEB= read_imu_log.html read_imu_log.js
CFLAGS += -Wall -I$(STAGING_DIR_HOST)/usr/include-uapi
LDLIBS += -lm
......@@ -33,6 +34,7 @@ install: $(PROGS)
$(INSTALL) -m $(INSTMODE) -o $(INSTOWNER) -g $(INSTGROUP) $(PROGS) $(DESTDIR)$(BINDIR)
$(INSTALL) -m $(INSTMODE) -o $(INSTOWNER) -g $(INSTGROUP) $(PHPSCRIPTS) $(DESTDIR)$(BINDIR)
$(INSTALL) -o $(INSTOWNER) -m $(INSTDOCS) $(PHPWEB) $(DESTDIR)$(WWW_PAGES)
$(INSTALL) -o $(INSTOWNER) -m $(INSTDOCS) $(WEB) $(DESTDIR)$(WWW_PAGES)
$(INSTALL) $(OWN)-d $(DESTDIR)$(VARHTML)
$(LN) -sf $(VARHTML) $(DESTDIR)$(WWW_PAGES)var
$(INSTALL) $(OWN)-d $(DESTDIR)$(CONFDIR)
......
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="author" content="?"/>
<script src="read_imu_log.js"></script>
<style>
#results td{
padding:0px 10px;
}
#results{
font-size:14px;
}
#controls{
background: rgba(100,200,100,0.5);
padding: 10px;
}
</style>
</head>
<body>
<table id='controls'>
<tr>
<td>
<table>
<tr>
<td>Filename: <input type='text' id='file' value='/home/root/imu.log' style='width:200px;' onchange='getRqStr()'></td>
</tr>
<tr>
<td colspan=''>Record filter:&nbsp;
<span title='External device'>EXT
<input id='filter_6' type='checkbox' checked onchange='getRqStr()'>
</span>&nbsp;&nbsp;
<span title='Image trigger signal'>IMG
<input id='filter_5' type='checkbox' checked onchange='getRqStr()'>
</span>&nbsp;&nbsp;
<span title='IMU'>IMU
<input id='filter_4' type='checkbox' checked onchange='getRqStr()'>
</span>&nbsp;&nbsp;
<span title='GPS'>GPS
<input id='filter_3' type='checkbox' checked onchange='getRqStr()'>
<input id='filter_2' type='checkbox' checked onchange='getRqStr()'>
<input id='filter_1' type='checkbox' checked onchange='getRqStr()'>
<input id='filter_0' type='checkbox' checked onchange='getRqStr()'>
</span>
</td>
</tr>
<tr>
<td>
<table>
<tr>
<td>Begin</td><td><input id='start' type='text' value='0' style='width:100px;text-align:right;' onchange='getRqStr()'></td>
</tr>
<tr>
<td>End</td><td><input id='end' type='text' value='5000' style='width:100px;text-align:right;' onchange='getRqStr()'></td>
</tr>
</table>
</td>
</tr>
<tr>
<td><button onclick='show()'>Show</button>&nbsp;&nbsp;<span id='csvlink'></span></td>
</tr>
</table>
</td>
</tr>
</table>
<div id='results'></div>
</body>
</html>
function init(){
console.log("init");
}
function show(){
console.log("show");
report("status: waiting for response");
var rqstr = getRqStr();
var request = new XMLHttpRequest();
request.open('GET', rqstr, true);
request.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var resp = this.responseText;
report("status: parsing response");
clearInterval(loading_interval);
parse_response(resp);
report("<a href='"+rqstr+"'>Download in CSV format</a>");
}
};
request.onerror = function() {
// There was a connection error of some sort
};
loading_interval = setInterval(loading,100);
request.send();
}
function getRqStr(){
var filename = document.getElementById("file").value;
var filter = 0;
for(var i=0;i<7;i++){
bit = (document.getElementById("filter_"+i).checked)?1:0;
filter += (bit<<i);
}
var start = document.getElementById("start").value;
var end = document.getElementById("end").value;
var n = end - start;
if (n<0) {
console.log("Error: Begin > End");
n = 1;
}
var rqstr = "read_imu_log.php?file="+filename+"&record="+start+"&nrecords="+n+"&filter="+filter;
report("");
setTimeout(function(){
report("<a href='"+rqstr+"'>Download in CSV format</a>");
},100);
return rqstr;
}
function parse_response(csv){
var t = CSVToArray(csv,",");
var result = "";
for(var i=0;i<t.length;i++){
if (t[i].length>0){
result += "<tr>";
for(var j=0;j<t[i].length;j++){
result += "<td>"+t[i][j]+"</td>";
} result += "</tr>";
}
}
document.getElementById("results").innerHTML = "<table>"+result+"</table>";
}
function report(msg){
document.getElementById("csvlink").innerHTML = msg;
}
var loading_interval;
function loading(){
console.log("loading");
}
//http://stackoverflow.com/questions/1293147/javascript-code-to-parse-csv-data
function CSVToArray( strData, strDelimiter ){
// Check to see if the delimiter is defined. If not,
// then default to comma.
strDelimiter = (strDelimiter || ",");
// Create a regular expression to parse the CSV values.
var objPattern = new RegExp(
(
// Delimiters.
"(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +
// Quoted fields.
"(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +
// Standard fields.
"([^\"\\" + strDelimiter + "\\r\\n]*))"
),
"gi"
);
// Create an array to hold our data. Give the array
// a default empty first row.
var arrData = [[]];
// Create an array to hold our individual pattern
// matching groups.
var arrMatches = null;
// Keep looping over the regular expression matches
// until we can no longer find a match.
while (arrMatches = objPattern.exec( strData )){
// Get the delimiter that was found.
var strMatchedDelimiter = arrMatches[ 1 ];
// Check to see if the given delimiter has a length
// (is not the start of string) and if it matches
// field delimiter. If id does not, then we know
// that this delimiter is a row delimiter.
if (
strMatchedDelimiter.length &&
strMatchedDelimiter !== strDelimiter
){
// Since we have reached a new row of data,
// add an empty row to our data array.
arrData.push( [] );
}
var strMatchedValue;
// Now that we have our delimiter out of the way,
// let's check to see which kind of value we
// captured (quoted or unquoted).
if (arrMatches[ 2 ]){
// We found a quoted value. When we capture
// this value, unescape any double quotes.
strMatchedValue = arrMatches[ 2 ].replace(
new RegExp( "\"\"", "g" ),
"\""
);
} else {
// We found a non-quoted value.
strMatchedValue = arrMatches[ 3 ];
}
// Now that we have our value string, let's add
// it to the data array.
arrData[ arrData.length - 1 ].push( strMatchedValue );
}
// Return the parsed data.
return( arrData );
}
\ No newline at end of file
<?php
if (!isset($_GET['file'])){
if (isset($_GET['file'])){
if (is_file($_GET['file'])){
$file = $_GET['file'];
$numRecordsInFile=filesize($file)/64;
}else{
echo "File not found";
die(0);
}
}else{
echo "<pre>\n";
echo "?file=log_file_name&record=record_number&nrecords=number_of_records&filter=filter";
echo "</pre>\n";
exit (0);
echo <<<TEXT
Usage: <b>http://address/read_imu_log.php?file=..&record=..&nrecords=..&filter=..</b>
* <b>file</b> - absolute path to file
* <b>record</b> - starting record index, default = 0
* <b>nrecords</b> - number of records to parse, default = 5000
* <b>filter</b> - filter out types of displayed records:
0x10 - display imu records only
0x20 - display image records only
0x40 - display external trigger records only
for gps records:
0x01 - display NMEA GPRMC records (have coordinates)
0x02 - display NMEA GPGGA records (have coordinates)
0x04 - display NMEA GPGSA records
0x08 - display NMEA GPVTG records,
default = 0x7f (display everything)
TEXT;
die(0);
}
//$timeShift = 21600; // 6 hrs
$timeShift = 0; // 6 hrs
if (isset($_GET['record'])) $record = $_GET['record']+0;
else $record=0;
if ($record>($numRecordsInFile-1)) $record=$numRecordsInFile-1;
if (isset($_GET['nrecords'])) $nRecords = $_GET['nrecords']+0;
else{
if ($numRecordsInFile>5000)
$nRecords=5000;
else
$nRecords=$numRecordsInFile;
}
$file=$_GET['file'];
$numRecordsInFile=filesize($file)/64;
$record=0;
$nRecords=1;
if ($nRecords>($numRecordsInFile-$record)) $nRecords= $numRecordsInFile-$record;
if (isset($_GET['filter'])) $filter= intval($_GET['filter'],0);
else $filter= 0x7f;
/*
1 - NMEA sentence 0 $GPRMC (log type 1)
2 - NMEA sentence 1 $GPGGA (log type 1)
......@@ -21,25 +55,22 @@ $nRecords=1;
16 - IMU (type 0)
32 - SYNC (type 2)
64 - ODOMETER (type 3)
*/
$filter=0x7f;
//$timeShift = 21600; // 6 hrs
$timeShift = 0; // 0 hrs
$type=-1;
$gpsType=-1;
if (isset($_GET['record'])) $record= $_GET['record']+0;
if (isset($_GET['nrecords'])) $nRecords= $_GET['nrecords']+0;
if (isset($_GET['filter'])) $filter= $_GET['filter']+0;
if ($record>($numRecordsInFile-1)) $record=$numRecordsInFile-1;
if ($nRecords>($numRecordsInFile-$record)) $nRecords= $numRecordsInFile-$record;
echo "<pre>\n";
echo "Number of samples in file=$numRecordsInFile\n";
echo "</pre>\n";
echo "Filename,$file\n";
echo "Found Records,$numRecordsInFile\n";
echo "Record filter,0x".dechex($filter)."\n";
echo "Start index,$record\n";
echo "End index,".($record+$nRecords)."\n\n";
$log_file=fopen($file,'r');
$averageIMU=array(
"number"=>0,
"gyroX"=> 0,
......@@ -56,97 +87,94 @@ $averageIMU=array(
"velocityZ"=>0,
"temperature"=>0);
$imuFieldOrder = array(
"gyroX",
"gyroY",
"gyroZ",
"accelX",
"accelY",
"accelZ",
"angleX",
"angleY",
"angleZ",
"velocityX",
"velocityY",
"velocityZ",
"temperature"
);
imuLogParse($log_file,$record,$nRecords,$filter);
exit(0);
die(0);
function imuLogParse($handle,$record,$nSamples,$filter,$tryNumber=10000){
global $timeShift;
global $averageIMU;
global $imuFieldOrder;
$showAll=($nSamples<=100000);
$gpsFilter= $filter&0xf;
$typeFilter=(($gpsFilter!=0)?2:0) | ((($filter&0x10)!=0)?1:0) | ((($filter&0x20)!=0)?4:0) | ((($filter&0x20)!=0)?8:0);
fseek($handle,64*$record,SEEK_SET);
echo "<pre>\n";
// echo "filter=$filter, gpsFilter=$gpsFilter, typeFilter=$typeFilter, record=$record, nSamples=$nSamples\n";
echo "Index,Timestamp,Type,".implode(",",$imuFieldOrder).",non-IMU data\n";
for ($nSample=0;$nSample<$nSamples;$nSample++) {
$sample=fread($handle,64);
$arr32=unpack('L*',$sample);
$time=(($arr32[1]&0xfffff)/1000000)+$arr32[2];
$type=$arr32[1]>>24;
$gps=($type==1)?($arr32[3]&0x3):0xf; // any if it is not GPS sample
if ((((1<<$type) & $typeFilter)!=0) && (($type!=1)|| (((1<<$gps) & $gpsFilter)!=0))) {
//$arr8=unpack('C*',$sample);
$time=(($arr32[1]&0xfffff)/1000000)+$arr32[2];
if ($showAll) printf("%8d %f: ",($record+$nSample),$time);
if ((((1<<$type)&$typeFilter)!=0) && (($type!=1) || (((1<<$gps)&$gpsFilter)!=0))) {
if ($showAll) printf("%8d,%f,$type,",($record+$nSample),$time);
switch ($type) {
// IMU record
// IMU record
case 0:
// print_r($arr32);
// if ($showAll) {
// for ($i=2;$i<16;$i++) {
// printf(" %9d",$arr32[$i+1]);
// }
// echo "\n";
// printf("%8d %f: ",($record+$nSample),$time);
// for ($i=2;$i<16;$i++) {
// printf(" %9x",0xffffffff&$arr32[$i+1]);
// }
// echo "\n";
// }
$imuSample=parseIMU($arr32);
//if ($showAll) print_r($imuSample);
if ($showAll) echo " [angleX]=>".$imuSample["angleX"]." [angleY]=>".$imuSample["angleY"]." [angleZ]=>".$imuSample["angleZ"].
echo implode(",",$imuSample)."\n";
/*
echo " [angleX]=>".$imuSample["angleX"]." [angleY]=>".$imuSample["angleY"]." [angleZ]=>".$imuSample["angleZ"].
" [gyroX] =>".$imuSample["gyroX"] ." [gyroY]=>".$imuSample["gyroY"] ." [gyroZ]=>".$imuSample["gyroZ"].
" [accelX] =>".$imuSample["accelX"] ." [accelY]=>".$imuSample["accelY"] ." [accelZ]=>".$imuSample["accelZ"].
" [velocityX] =>".$imuSample["velocityX"] ." [velocityY]=>".$imuSample["velocityY"] ." [velocityZ]=>".$imuSample["velocityZ"].
" [temperature]=>".$imuSample["temperature"]."\n";
$averageIMU["number"]++;
foreach ($imuSample as $key=>$value) $averageIMU[$key]+=$value;
$avg_x = $averageIMU["angleX"]/$averageIMU["number"];
$avg_y = $averageIMU["angleY"]/$averageIMU["number"];
$avg_z = $averageIMU["angleZ"]/$averageIMU["number"];
//echo $avg_x." ".$avg_y." ".$avg_z."\n";
*/
break;
// GPS record
// GPS record
case 1:
$nmeaArray=parseGPS($sample);
$nmeaString='$';
for ($i=0; $i<count($nmeaArray);$i++) {
$nmeaString.=$nmeaArray[$i];
if ($i < (count($nmeaArray)-1))$nmeaString.=',';
}
echo "GPS (NMEA): ".$nmeaString."\n";
$nmeaString = '$'.implode(",",$nmeaArray);
echo ",,,,,,,,,,,,,\"GPS (NMEA): ".$nmeaString."\"\n";
break;
// Master (Sync) record
// Master (Sync) record
case 2:
$masterTime=(($arr32[3]&0xfffff)/1000000)+$arr32[4];
$subchannel = ($arr32[3] >> 24);
echo "Subchannel: <b>".$subchannel."</b> MasterTimeStamp: <b>".($masterTime+$timeShift)."</b> TimeStamp: <b>".($time+$timeShift)."</b> MasterTimeStamp(precise): 0x".dechex($arr32[4])."+".dechex($arr32[3])." TimeStamp(precise): 0x".dechex($arr32[2])."+".dechex($arr32[1])." $masterTime - ".gmdate(DATE_RFC850,$masterTime)." [local timestamp - ".gmdate(DATE_RFC850,$time)."]\n";
echo ",,,,,,,,,,,,,\"Subchannel: <b>".$subchannel."</b> MasterTimeStamp: <b>".($masterTime+$timeShift)."</b> TimeStamp: <b>".($time+$timeShift)."</b> MasterTimeStamp(precise): 0x".dechex($arr32[4])."+".dechex($arr32[3])." TimeStamp(precise): 0x".dechex($arr32[2])."+".dechex($arr32[1])." $masterTime - ".gmdate(DATE_RFC850,$masterTime)." [local timestamp - ".gmdate(DATE_RFC850,$time)."]\"\n";
break;
// Show hex data
// Show hex data
case 3: print_r($arr32);
break;
}
}
}
if ($averageIMU['number']>0) {
foreach ( $averageIMU as $key => $value )
if ($key != 'number')
$averageIMU [$key] /= $averageIMU ['number'];
print_r ( $averageIMU );
echo "</pre>\n";
echo "<table>\n";
foreach ( $averageIMU as $key => $value )
echo "<tr><td>$key</td><td>$value</td></tr>\n";
echo "</table>\n";
}
}
function parseGPS($sample){
......@@ -162,19 +190,19 @@ function parseGPS($sample){
2=>str_split('bnnnnnnnnnnnnnnnn'),
3=>str_split('nbnbnbnb')
);
//print_r($formats);
/*
//print_r($formats);
/*
'R','M','C','n','b','n','b','n','b','n','n','n','n','b', 0, 0, 0, 0, 0, 0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
'G','G','A','n','n','b','n','b','n','n','n','n','b','n','b','b','b', 0, 0, 0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
'G','S','A','b','n','n','n','n','n','n','n','n','n','n','n','n','n','n','n','n', 0,0,0,0, 0,0,0,0, 0,0,0,0,
'V','T','G','n','b','n','b','n','b','n','b', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
*/
*/
$arr8= unpack('C*',$sample);
$type=$arr8[4];
$nibbleNumber=16; // starting with 0;
$gps=getNibble($nibbleNumber++,$arr8);
//echo "gps=$gps\n";
$rslt=array(0=>$sentences[$gps]);
for ($i=0;$i<count($formats[$gps]);$i++){
$rslt[$i+1]='';
......@@ -194,11 +222,44 @@ function parseGPS($sample){
}
return $rslt;
}
function getNibble($n,$arr8){
return ($arr8[($n>>1)+1]>>(($n&1)?4:0))&0xf;
}
function parseNMEA($sent,$data){
function parseIMU ($arr32){
$gyroScale=0.013108/65536; // deg/sec
$accelScale=0.8192/65536; // mg
$angleScale= 0.005493/65536; // degrees
$velocityScale=0.0030518/65536; // m/sec
//$angleScale= 0.005493; //degrees
//$velocityScale=0.0030518; //m/sec
$temperatureScale=0.00565; // C/LSB
$t=($arr32[15] & 0xffff);
if ($t>=32768) $t-=65536;
for ($i=3;$i<15;$i++) if ((($arr32[$i] & 0x80000000)!=0) && ($arr32[$i] > 0)) $arr32[$i]-=0x100000000;
return array(
"gyroX"=> $arr32[ 3]*$gyroScale,
"gyroY"=> $arr32[ 4]*$gyroScale,
"gyroZ"=> $arr32[ 5]*$gyroScale,
"accelX"=>$arr32[ 6]*$accelScale,
"accelY"=>$arr32[ 7]*$accelScale,
"accelZ"=>$arr32[ 8]*$accelScale,
"angleX"=>$arr32[ 9]*$angleScale,
"angleY"=>$arr32[10]*$angleScale,
"angleZ"=>$arr32[11]*$angleScale,
"velocityX"=>$arr32[12]*$velocityScale,
"velocityY"=>$arr32[13]*$velocityScale,
"velocityZ"=>$arr32[14]*$velocityScale,
"temperature"=>$t*$temperatureScale+25
);
}
/*
function parseNMEA($sent,$data){
eg4. $GPRMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,ddmmyy,x.x,a*hh
1 = UTC of position fix
2 = Data status (V=navigation receiver warning)
......@@ -297,37 +358,7 @@ eg3. $GPVTG,t,T,,,s.ss,N,s.ss,K*hh
0x72, // time d/h [12:8] - day [5:0] - hours
0x74,// time y/m [14:8] year (from 2000), [3:0] - month
*/
}
function parseIMU ($arr32){
$gyroScale=0.013108/65536; // deg/sec
$accelScale=0.8192/65536; // mg
$angleScale= 0.005493/65536; //degrees
$velocityScale=0.0030518/65536; //m/sec
// $angleScale= 0.005493; //degrees
// $velocityScale=0.0030518; //m/sec
$temperatureScale=0.00565; // C/LSB
$t=($arr32[15] & 0xffff);
if ($t>=32768) $t-=65536;
for ($i=3;$i<15;$i++) if ((($arr32[$i] & 0x80000000)!=0) && ($arr32[$i] > 0)) $arr32[$i]-=0x100000000;
return array(
"gyroX"=> $arr32[ 3]*$gyroScale,
"gyroY"=> $arr32[ 4]*$gyroScale,
"gyroZ"=> $arr32[ 5]*$gyroScale,
"accelX"=>$arr32[ 6]*$accelScale,
"accelY"=>$arr32[ 7]*$accelScale,
"accelZ"=>$arr32[ 8]*$accelScale,
"angleX"=>$arr32[ 9]*$angleScale,
"angleY"=>$arr32[10]*$angleScale,
"angleZ"=>$arr32[11]*$angleScale,
"velocityX"=>$arr32[12]*$velocityScale,
"velocityY"=>$arr32[13]*$velocityScale,
"velocityZ"=>$arr32[14]*$velocityScale,
"temperature"=>$t*$temperatureScale+25
// "temperature"=>$t
// date/time
);
}
*/
?>
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