let allAccSerial = [] let allSerialCoords = [] let allTcpCoords = [] var ctx = document.getElementById('accChart').getContext('2d'); var accChart = new Chart(ctx, { type: 'line', data: { labels: [], datasets: [{ label: 'Ublox Horizontal acc. (m)', backgroundColor: 'rgba(255, 255, 255, 1)', borderColor: 'rgba(255, 255, 255, 1)', borderWidth: 1, fill: false, pointRadius: 0.5, lineTension: 0.5, data: [] }, { label: 'Smartphone Horizontal acc. (m)', backgroundColor: 'rgb(185,190,45)', borderColor: 'rgb(185,190,45)', borderWidth: 1, fill: false, pointRadius: 0.5, lineTension: 0.5, data: [] }, { label: 'Distance Ublox - Smartphone (m)', backgroundColor: 'rgba(30, 130, 76, 1)', borderColor: 'rgba(30, 130, 76, 1)', borderWidth: 1, fill: false, pointRadius: 0.5, lineTension: 0.5, data: [] }] }, options: { scales: { yAxes: [{ ticks: { min: 0, max: 20, } }], xAxes: [{ type: 'time', time: { unit: 'second' } }] }, animation: { duration: 0 } } }); function addDistances(tcpDataList, serialDataList){ let tcpCoords = [] let serialCoords = [] let tcpTimes = [] let serialHAccs = [] let distances = [] indexes.forEach(index => { serialHAccs.push(allAccSerial[index].toFixed(2)) serialCoords.push(allSerialCoords[index]) }) tcpDataList.forEach(sensordata => { if(!(sensordata.Speed === 0) && !(sensordata.HAcc === 0)){ if (!(sensordata.Position[0] === 0) && !(sensordata.Position[1] === 0)) { let tcpCoord = [sensordata.Position[1], sensordata.Position[0]] tcpCoords.push(tcpCoord) let time = sensordata.Timestamp tcpTimes.push(time) } } }) for(let i = 0; i < tcpCoords.length; i++){ let distance = distanceInMetersBetweenEarthCoordinates(serialCoords[i],tcpCoords[i]) distances.push(distance) } console.log("tcp coords: " + tcpCoords) console.log("distances: " + distances) accChart.data.labels = tcpTimes accChart.data.datasets[0].data = serialHAccs accChart.data.datasets[1].data = distances accChart.update() } function addDistancesNew(data){ let serialHAccs = data.map(el => { return el.ser.HAcc }) let tcpHAccs = data.map(el => { return el.tcp.HAcc }) let distances = data.map((el, i, arr) => { // return distVincenty(el.ser.Position, el.tcp.Position) const plaindist = distVincenty(el.ser.Position, el.tcp.Position) arr[i]['distance'] = plaindist arr[i]['distanceClean'] = plaindist - (el.ser.Speed / 1000 * el.differenceMs) arr[i]['distanceCleanAbs'] = plaindist - Math.abs(el.ser.Speed / 1000 * el.differenceMs) return plaindist //- Math.abs(el.ser.Speed / 1000 * el.differenceMs) }) let tcpTimes = data.map(el => { return el.tcp.Timestamp }) accChart.data.labels = tcpTimes accChart.data.datasets[0].data = serialHAccs accChart.data.datasets[1].data = tcpHAccs accChart.data.datasets[2].data = distances accChart.update() } //https://www.movable-type.co.uk/scripts/latlong.html function distanceInMetersBetweenEarthCoordinates(coord1, coord2) { var long1 = coord1[0] var lat1 = coord1[1] var long2 = coord2[0] var lat2 = coord2[1] var earthRadiusM = 6371000 var phi1 = lat1 * Math.PI / 180 var phi2 = lat2 * Math.PI / 180 var dlat = (lat2-lat1) * Math.PI / 180 var dlong = (long2 - long1) * Math.PI / 180 var a = Math.sin(dlat/2) * Math.sin(dlat/2) + Math.cos(phi1) * Math.cos(phi2) * Math.sin(dlong/2) * Math.sin(dlong/2) var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)) return earthRadiusM * c } Number.prototype.toRad = function () { return this * Math.PI / 180; } function distVincenty(coord1, coord2) { const lon1 = coord1[0] const lat1 = coord1[1] const lon2 = coord2[0] const lat2 = coord2[1] var a = 6378137, b = 6356752.314245, f = 1/298.257223563; // WGS-84 ellipsoid params var L = (lon2-lon1).toRad() var U1 = Math.atan((1-f) * Math.tan(lat1.toRad())); var U2 = Math.atan((1-f) * Math.tan(lat2.toRad())); var sinU1 = Math.sin(U1), cosU1 = Math.cos(U1); var sinU2 = Math.sin(U2), cosU2 = Math.cos(U2); var lambda = L, lambdaP, iterLimit = 100; do { var sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda); var sinSigma = Math.sqrt((cosU2*sinLambda) * (cosU2*sinLambda) + (cosU1*sinU2-sinU1*cosU2*cosLambda) * (cosU1*sinU2-sinU1*cosU2*cosLambda)); if (sinSigma===0) return 0; // co-incident points var cosSigma = sinU1*sinU2 + cosU1*cosU2*cosLambda; var sigma = Math.atan2(sinSigma, cosSigma); var sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma; var cosSqAlpha = 1 - sinAlpha*sinAlpha; var cos2SigmaM = cosSigma - 2*sinU1*sinU2/cosSqAlpha; if (isNaN(cos2SigmaM)) cos2SigmaM = 0; // equatorial line: cosSqAlpha=0 (ยง6) var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha)); lambdaP = lambda; lambda = L + (1-C) * f * sinAlpha * (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM))); } while (Math.abs(lambda-lambdaP) > 1e-12 && --iterLimit>0); if (iterLimit===0) return NaN // formula failed to converge var uSq = cosSqAlpha * (a*a - b*b) / (b*b); var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq))); var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq))); var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)- B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM))); var s = b*A*(sigma-deltaSigma); s = s.toFixed(3); // round to 1mm precision return s; }