Skip to content

Commit 62978cc

Browse files
demvladhaslinghuis
andauthored
Added cartesian gps coords relative home point as additional computed fields (betaflight#773)
* added gps coords transform module gps_transform.js * Added computed fields for coords in cartesian system * added coords values at curves legend * The home distance id added as computed field * added friendly names for gps cartesian coords * added using of gps home points altitude if it exists in log file * gps coord names are changed * Added example graphs for GPS Cartesian coords data * code issues are resolved * code issues are resolved * code issues are resolved * code style improvement * Field name is improved Co-authored-by: Mark Haslinghuis <[email protected]> * Code style improvement Co-authored-by: Mark Haslinghuis <[email protected]> * Code style improvement Co-authored-by: Mark Haslinghuis <[email protected]> * Code style improvement Co-authored-by: Mark Haslinghuis <[email protected]> * Code style improvement Co-authored-by: Mark Haslinghuis <[email protected]> * Code style improvement Co-authored-by: Mark Haslinghuis <[email protected]> * Update gps_transform.js * Code style improvement * Code style improvement * Code style improvement --------- Co-authored-by: Mark Haslinghuis <[email protected]>
1 parent f3b680b commit 62978cc

File tree

4 files changed

+125
-7
lines changed

4 files changed

+125
-7
lines changed

src/flightlog.js

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { FlightLogIndex } from "./flightlog_index";
22
import { FlightLogParser } from "./flightlog_parser";
3+
import { GPS_transform } from "./gps_transform";
34
import {
45
MAX_MOTOR_NUMBER,
56
DSHOT_MIN_VALUE,
@@ -29,7 +30,7 @@ import {
2930
* Window based smoothing of fields is offered.
3031
*/
3132
export function FlightLog(logData) {
32-
let ADDITIONAL_COMPUTED_FIELD_COUNT = 15 /** attitude + PID_SUM + PID_ERROR + RCCOMMAND_SCALED **/,
33+
let ADDITIONAL_COMPUTED_FIELD_COUNT = 19 /** attitude + PID_SUM + PID_ERROR + RCCOMMAND_SCALED + GPS coord**/,
3334
that = this,
3435
logIndex = 0,
3536
logIndexes = new FlightLogIndex(logData),
@@ -44,7 +45,8 @@ export function FlightLog(logData) {
4445
// Map from field indexes to smoothing window size in microseconds
4546
fieldSmoothing = {},
4647
maxSmoothing = 0,
47-
smoothedCache = new FIFOCache(2);
48+
smoothedCache = new FIFOCache(2),
49+
gpsTransform = null;
4850

4951
//Public fields:
5052
this.parser = parser;
@@ -130,7 +132,7 @@ export function FlightLog(logData) {
130132
index = index ?? logIndex;
131133
return logIndexes.getIntraframeDirectory(index).maxTime;
132134
};
133-
135+
134136
this.getActualLoggedTime = function (index) {
135137
index = index ?? logIndex;
136138
const directory = logIndexes.getIntraframeDirectory(index);
@@ -281,6 +283,9 @@ export function FlightLog(logData) {
281283
if (!that.isFieldDisabled().GYRO && !that.isFieldDisabled().SETPOINT) {
282284
fieldNames.push("axisError[0]", "axisError[1]", "axisError[2]"); // Custom calculated error field
283285
}
286+
if (!that.isFieldDisabled().GPS) {
287+
fieldNames.push("gpsCartesianCoords[0]", "gpsCartesianCoords[1]", "gpsCartesianCoords[2]", "gpsDistance"); // GPS coords in cartesian system
288+
}
284289

285290
fieldNameToIndex = {};
286291
for (let i = 0; i < fieldNames.length; i++) {
@@ -518,10 +523,11 @@ export function FlightLog(logData) {
518523
lastSlow[i] = frame[i];
519524
}
520525
break;
521-
case "H":
522-
// TODO
523-
// contains coordinates only
524-
// should be handled separately
526+
case "H": {
527+
const homeAltitude = frame.length > 2 ? frame[2] / 10 : 0; // will work after BF firmware improvement
528+
gpsTransform = new GPS_transform(frame[0] / 10000000, frame[1] / 10000000, homeAltitude, 0.0);
529+
break;
530+
}
525531
case "G":
526532
// The frameValid can be false, when no GPS home (the G frames contains GPS position as diff of GPS Home position).
527533
// But other data from the G frame can be valid (time, num sats)
@@ -631,6 +637,11 @@ export function FlightLog(logData) {
631637
fieldNameToIndex["setpoint[2]"],
632638
fieldNameToIndex["setpoint[3]"],
633639
];
640+
let gpsCoord = [
641+
fieldNameToIndex["GPS_coord[0]"],
642+
fieldNameToIndex["GPS_coord[1]"],
643+
fieldNameToIndex["GPS_altitude"],
644+
];
634645

635646
const flightModeFlagsIndex = fieldNameToIndex["flightModeFlags"]; // This points to the flightmode data
636647

@@ -690,6 +701,11 @@ export function FlightLog(logData) {
690701
axisPID = false;
691702
}
692703

704+
if (!gpsCoord[0]) {
705+
gpsCoord = false;
706+
}
707+
708+
693709
sourceChunkIndex = 0;
694710
destChunkIndex = 0;
695711

@@ -830,6 +846,22 @@ export function FlightLog(logData) {
830846
}
831847
}
832848

849+
// Calculate cartesian coords by GPS
850+
if (!that.isFieldDisabled().GPS) {
851+
if (gpsTransform && gpsCoord && srcFrame[gpsCoord[0]]) {
852+
const gpsCartesianCoords = gpsTransform.WGS_BS(srcFrame[gpsCoord[0]] / 10000000, srcFrame[gpsCoord[1]] / 10000000, srcFrame[gpsCoord[2]] / 10);
853+
destFrame[fieldIndex++] = gpsCartesianCoords.x;
854+
destFrame[fieldIndex++] = gpsCartesianCoords.y;
855+
destFrame[fieldIndex++] = gpsCartesianCoords.z;
856+
destFrame[fieldIndex++] = Math.sqrt(gpsCartesianCoords.x * gpsCartesianCoords.x + gpsCartesianCoords.z * gpsCartesianCoords.z);
857+
} else {
858+
destFrame[fieldIndex++] = 0;
859+
destFrame[fieldIndex++] = 0;
860+
destFrame[fieldIndex++] = 0;
861+
destFrame[fieldIndex++] = 0;
862+
}
863+
}
864+
833865
// Remove empty fields at the end
834866
destFrame.splice(fieldIndex);
835867
}

src/flightlog_fields_presenter.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ const FRIENDLY_FIELD_NAMES = {
124124
GPS_altitude: "GPS Altitude ASL",
125125
GPS_speed: "GPS Speed",
126126
GPS_ground_course: "GPS Heading",
127+
128+
"gpsCartesianCoords[all]": "GPS Coords",
129+
"gpsCartesianCoords[0]": "GPS Coords [X]",
130+
"gpsCartesianCoords[1]": "GPS Coords [Y]",
131+
"gpsCartesianCoords[2]": "GPS Coords [Z]",
132+
gpsDistance: "GPS Home distance",
127133
};
128134

129135
const DEBUG_FRIENDLY_FIELD_NAMES_INITIAL = {
@@ -1639,6 +1645,12 @@ FlightLogFieldPresenter.decodeFieldToFriendly = function (
16391645
}
16401646
case "GPS_ground_course":
16411647
return `${(value / 10).toFixed(1)} °`;
1648+
1649+
case "gpsCartesianCoords[0]":
1650+
case "gpsCartesianCoords[1]":
1651+
case "gpsCartesianCoords[2]":
1652+
case "gpsDistance":
1653+
return `${value.toFixed(0)} m`;
16421654

16431655
case "debug[0]":
16441656
case "debug[1]":

src/gps_transform.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
export function GPS_transform(Lat0, Lon0, H0, Heading) {
2+
3+
function deg2rad(deg) {
4+
return deg * Math.PI / 180.0;
5+
}
6+
7+
Lat0 = deg2rad(Lat0);
8+
Lon0 = deg2rad(Lon0);
9+
const Semimajor = 6378137.0,
10+
Flat = 1.0 / 298.257223563,
11+
Ecc_2 = Flat * (2 - Flat),
12+
SinB = Math.sin(Lat0),
13+
CosB = Math.cos(Lat0),
14+
SinL = Math.sin(Lon0),
15+
CosL = Math.cos(Lon0),
16+
N = Semimajor / Math.sqrt(1.0 - Ecc_2 * SinB * SinB),
17+
18+
a11 = -SinB * CosL,
19+
a12 = -SinB * SinL,
20+
a13 = CosB,
21+
a21 = -SinL,
22+
a22 = CosL,
23+
a23 = 0,
24+
a31 = CosL * CosB,
25+
a32 = CosB * SinL,
26+
a33 = SinB,
27+
28+
X0 = (N + H0) * CosB * CosL,
29+
Y0 = (N + H0) * CosB * SinL,
30+
Z0 = (N + H0 - Ecc_2 * N) * SinB,
31+
c11 = Math.cos( deg2rad(Heading) ),
32+
c12 = Math.sin( deg2rad(Heading) ),
33+
c21 = -c12,
34+
c22 = c11;
35+
36+
this.WGS_ECEF = function (Lat, Lon, H) {
37+
Lat = deg2rad(Lat);
38+
Lon = deg2rad(Lon);
39+
const
40+
SinB = Math.sin(Lat),
41+
CosB = Math.cos(Lat),
42+
SinL = Math.sin(Lon),
43+
CosL = Math.cos(Lon),
44+
N = Semimajor / Math.sqrt(1 - Ecc_2 * SinB * SinB);
45+
46+
return {
47+
x: (N + H) * CosB * CosL,
48+
y: (N + H) * CosB * SinL,
49+
z: (N + H - Ecc_2 * N) * SinB,
50+
};
51+
};
52+
53+
this.ECEF_BS = function (pos) {
54+
const PosX1= a11 * (pos.x - X0) + a12 * (pos.y - Y0) + a13 * (pos.z - Z0);
55+
const PosZ1= a21 * (pos.x - X0) + a22 * (pos.y - Y0) + a23 * (pos.z - Z0);
56+
57+
return {
58+
x: c11 * PosX1 + c12 * PosZ1,
59+
y: a31 * (pos.x - X0) + a32 * (pos.y - Y0) + a33 * (pos.z - Z0),
60+
z: c21 * PosX1 + c22 * PosZ1,
61+
};
62+
};
63+
64+
this.WGS_BS = function (Lat, Lon, H) {
65+
return this.ECEF_BS(this.WGS_ECEF(Lat, Lon, H));
66+
};
67+
}

src/graph_config.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,6 +1537,13 @@ GraphConfig.getExampleGraphConfigs = function (flightLog, graphNames) {
15371537
"GPS_coord[all]",
15381538
],
15391539
});
1540+
EXAMPLE_GRAPHS.push({
1541+
label: "GPS Cartesian coords",
1542+
fields: [
1543+
"gpsCartesianCoords[all]",
1544+
"gpsDistance",
1545+
],
1546+
});
15401547
}
15411548

15421549
for (const srcGraph of EXAMPLE_GRAPHS) {

0 commit comments

Comments
 (0)