Loading src/Makefile +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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) Loading src/read_imu_log.html 0 → 100644 +69 −0 Original line number Diff line number Diff line <!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: <span title='External device'>EXT <input id='filter_6' type='checkbox' checked onchange='getRqStr()'> </span> <span title='Image trigger signal'>IMG <input id='filter_5' type='checkbox' checked onchange='getRqStr()'> </span> <span title='IMU'>IMU <input id='filter_4' type='checkbox' checked onchange='getRqStr()'> </span> <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> <span id='csvlink'></span></td> </tr> </table> </td> </tr> </table> <div id='results'></div> </body> </html> src/read_imu_log.js 0 → 100644 +171 −0 Original line number Diff line number Diff line 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 src/read_imu_log.php +145 −114 Original line number Diff line number Diff line <?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; $file=$_GET['file']; $numRecordsInFile=filesize($file)/64; $record=0; $nRecords=1; if ($record>($numRecordsInFile-1)) $record=$numRecordsInFile-1; if (isset($_GET['nrecords'])) $nRecords = $_GET['nrecords']+0; else{ if ($numRecordsInFile>5000) $nRecords=5000; else $nRecords=$numRecordsInFile; } 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) Loading @@ -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, Loading @@ -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 ($showAll) printf("%8d,%f,$type,",($record+$nSample),$time); switch ($type) { // 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 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 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 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){ Loading Loading @@ -174,7 +202,7 @@ function parseGPS($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]=''; Loading @@ -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) Loading Loading @@ -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 ); } ?> Loading
src/Makefile +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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) Loading
src/read_imu_log.html 0 → 100644 +69 −0 Original line number Diff line number Diff line <!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: <span title='External device'>EXT <input id='filter_6' type='checkbox' checked onchange='getRqStr()'> </span> <span title='Image trigger signal'>IMG <input id='filter_5' type='checkbox' checked onchange='getRqStr()'> </span> <span title='IMU'>IMU <input id='filter_4' type='checkbox' checked onchange='getRqStr()'> </span> <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> <span id='csvlink'></span></td> </tr> </table> </td> </tr> </table> <div id='results'></div> </body> </html>
src/read_imu_log.js 0 → 100644 +171 −0 Original line number Diff line number Diff line 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
src/read_imu_log.php +145 −114 Original line number Diff line number Diff line <?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; $file=$_GET['file']; $numRecordsInFile=filesize($file)/64; $record=0; $nRecords=1; if ($record>($numRecordsInFile-1)) $record=$numRecordsInFile-1; if (isset($_GET['nrecords'])) $nRecords = $_GET['nrecords']+0; else{ if ($numRecordsInFile>5000) $nRecords=5000; else $nRecords=$numRecordsInFile; } 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) Loading @@ -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, Loading @@ -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 ($showAll) printf("%8d,%f,$type,",($record+$nSample),$time); switch ($type) { // 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 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 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 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){ Loading Loading @@ -174,7 +202,7 @@ function parseGPS($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]=''; Loading @@ -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) Loading Loading @@ -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 ); } ?>