diff --git a/gcs/src/components/missions/fenceItemsTableRow.jsx b/gcs/src/components/missions/fenceItemsTableRow.jsx
index 5ba378300..ea5931343 100644
--- a/gcs/src/components/missions/fenceItemsTableRow.jsx
+++ b/gcs/src/components/missions/fenceItemsTableRow.jsx
@@ -11,11 +11,12 @@ import {
} from "@mantine/core"
import { IconArrowDown, IconArrowUp, IconTrash } from "@tabler/icons-react"
import { useEffect, useState } from "react"
-import { coordToInt, intToCoord } from "../../helpers/dataFormatters"
import {
- FENCE_ITEM_COMMANDS_LIST,
- MAV_FRAME_LIST,
-} from "../../helpers/mavlinkConstants"
+ coordToInt,
+ getPositionFrameName,
+ intToCoord,
+} from "../../helpers/dataFormatters"
+import { FENCE_ITEM_COMMANDS_LIST } from "../../helpers/mavlinkConstants"
const coordsFractionDigits = 9
@@ -38,16 +39,6 @@ function getAvailableCommands() {
}))
}
-function getFrameName(frameId) {
- var frameName = MAV_FRAME_LIST[frameId]
-
- if (frameName.startsWith("MAV_FRAME_")) {
- frameName = frameName.replace("MAV_FRAME_", "")
- }
-
- return frameName || "UNKNOWN"
-}
-
export default function FenceItemsTableRow({
index,
fenceItem,
@@ -120,7 +111,7 @@ export default function FenceItemsTableRow({
hideControls
/>
- {getFrameName(fenceItemData.frame)}
+ {getPositionFrameName(fenceItemData.frame)}
updateMissionItemOrder(fenceItemData.id, -1)}
diff --git a/gcs/src/components/missions/missionItemsTableRow.jsx b/gcs/src/components/missions/missionItemsTableRow.jsx
index 6ac80dee7..f8d1feaad 100644
--- a/gcs/src/components/missions/missionItemsTableRow.jsx
+++ b/gcs/src/components/missions/missionItemsTableRow.jsx
@@ -11,10 +11,13 @@ import {
} from "@mantine/core"
import { IconArrowDown, IconArrowUp, IconTrash } from "@tabler/icons-react"
import { useEffect, useState } from "react"
-import { coordToInt, intToCoord } from "../../helpers/dataFormatters"
+import {
+ coordToInt,
+ getPositionFrameName,
+ intToCoord,
+} from "../../helpers/dataFormatters"
import {
COPTER_MISSION_ITEM_COMMANDS_LIST,
- MAV_FRAME_LIST,
PLANE_MISSION_ITEM_COMMANDS_LIST,
} from "../../helpers/mavlinkConstants"
@@ -60,16 +63,6 @@ export default function MissionItemsTableRow({
}))
}
- function getFrameName(frameId) {
- var frameName = MAV_FRAME_LIST[frameId]
-
- if (frameName.startsWith("MAV_FRAME_")) {
- frameName = frameName.replace("MAV_FRAME_", "")
- }
-
- return frameName || "UNKNOWN"
- }
-
function updateMissionItemData(key, newVal) {
setMissionItemData({
...missionItemData,
@@ -139,7 +132,7 @@ export default function MissionItemsTableRow({
hideControls
/>
- {getFrameName(missionItemData.frame)}
+ {getPositionFrameName(missionItemData.frame)}
updateMissionItemOrder(missionItemData.id, -1)}
diff --git a/gcs/src/components/missions/rallyItemsTableRow.jsx b/gcs/src/components/missions/rallyItemsTableRow.jsx
index 33afce1b8..e902f9730 100644
--- a/gcs/src/components/missions/rallyItemsTableRow.jsx
+++ b/gcs/src/components/missions/rallyItemsTableRow.jsx
@@ -11,8 +11,11 @@ import {
} from "@mantine/core"
import { IconTrash } from "@tabler/icons-react"
import { useEffect, useState } from "react"
-import { coordToInt, intToCoord } from "../../helpers/dataFormatters"
-import { MAV_FRAME_LIST } from "../../helpers/mavlinkConstants"
+import {
+ coordToInt,
+ getPositionFrameName,
+ intToCoord,
+} from "../../helpers/dataFormatters"
const coordsFractionDigits = 9
export default function RallyItemsTableRow({
@@ -31,16 +34,6 @@ export default function RallyItemsTableRow({
updateRallyItem(rallyItemData)
}, [rallyItemData])
- function getFrameName(frameId) {
- var frameName = MAV_FRAME_LIST[frameId]
-
- if (frameName.startsWith("MAV_FRAME_")) {
- frameName = frameName.replace("MAV_FRAME_", "")
- }
-
- return frameName || "UNKNOWN"
- }
-
function updateRallyItemData(key, newVal) {
setRallyItemData({
...rallyItemData,
@@ -92,7 +85,7 @@ export default function RallyItemsTableRow({
hideControls
/>
- {getFrameName(rallyItemData.frame)}
+ {getPositionFrameName(rallyItemData.frame)}
deleteRallyItem(rallyItemData.id)}
diff --git a/gcs/src/helpers/dataFormatters.js b/gcs/src/helpers/dataFormatters.js
index 6fd634e3a..d288829e8 100644
--- a/gcs/src/helpers/dataFormatters.js
+++ b/gcs/src/helpers/dataFormatters.js
@@ -1,3 +1,5 @@
+import { MAV_FRAME_LIST } from "./mavlinkConstants"
+
function radToDeg(val) {
return (val * 180) / Math.PI
}
@@ -16,3 +18,17 @@ export const dataFormatters = {
"ATTITUDE.roll": radToDeg,
"ATTITUDE.yaw": radToDeg,
}
+
+export function getPositionFrameName(frameId) {
+ if (frameId === undefined || frameId === null) {
+ return "UNKNOWN"
+ }
+
+ var frameName = MAV_FRAME_LIST[frameId]
+
+ if (frameName.startsWith("MAV_FRAME_")) {
+ frameName = frameName.replace("MAV_FRAME_", "")
+ }
+
+ return frameName || "UNKNOWN"
+}
diff --git a/gcs/src/missions.jsx b/gcs/src/missions.jsx
index 23dc359fa..c98549406 100644
--- a/gcs/src/missions.jsx
+++ b/gcs/src/missions.jsx
@@ -65,6 +65,9 @@ export default function Missions() {
const [activeTab, setActiveTab] = useState("mission")
+ // Need to keep a reference to the active tab to avoid stale closures
+ const activeTabRef = useRef(activeTab)
+
// Mission data
const [missionItems, setMissionItems] = useSessionStorage({
key: "missionItems",
@@ -258,6 +261,10 @@ export default function Missions() {
}
}, [importFile])
+ useEffect(() => {
+ activeTabRef.current = activeTab
+ }, [activeTab])
+
function resetMissionProgressModalData() {
setMissionProgressModalData({
message: "",
@@ -304,11 +311,15 @@ export default function Missions() {
z: newMissionItemAltitude,
frame: parseInt(
Object.keys(MAV_FRAME_LIST).find(
- (key) => MAV_FRAME_LIST[key] === "MAV_FRAME_GLOBAL_RELATIVE_ALT",
+ (key) =>
+ MAV_FRAME_LIST[key] ===
+ (activeTabRef.current === "fence"
+ ? "MAV_FRAME_GLOBAL"
+ : "MAV_FRAME_GLOBAL_RELATIVE_ALT"),
),
),
command: null,
- param1: activeTab === "fence" ? 5 : 0,
+ param1: activeTabRef.current === "fence" ? 5 : 0,
param2: 0,
param3: 0,
param4: 0,
@@ -320,19 +331,19 @@ export default function Missions() {
mavpackettype: "MISSION_ITEM_INT",
}
- if (activeTab === "mission") {
+ if (activeTabRef.current === "mission") {
newMissionItem.seq = missionItems.length
newMissionItem.command = 16 // MAV_CMD_NAV_WAYPOINT
newMissionItem.mission_type = 0 // Mission type
setMissionItems((prevItems) => [...prevItems, newMissionItem])
- } else if (activeTab === "fence") {
+ } else if (activeTabRef.current === "fence") {
newMissionItem.seq = fenceItems.length
newMissionItem.command = 5004 // MAV_CMD_NAV_FENCE_CIRCLE_EXCLUSION
newMissionItem.mission_type = 1 // Fence type
setFenceItems((prevItems) => [...prevItems, newMissionItem])
- } else if (activeTab === "rally") {
+ } else if (activeTabRef.current === "rally") {
newMissionItem.seq = rallyItems.length
newMissionItem.command = 5100 // MAV_CMD_NAV_RALLY_POINT
newMissionItem.mission_type = 2 // Rally type
@@ -368,11 +379,11 @@ export default function Missions() {
target_component: targetInfo.target_component,
target_system: targetInfo.target_system,
mission_type:
- activeTab === "mission"
+ activeTabRef.current === "mission"
? 0
- : activeTab === "fence"
+ : activeTabRef.current === "fence"
? 1
- : activeTab === "rally"
+ : activeTabRef.current === "rally"
? 2
: 0, // Default to 0 (Mission type) if activeTab is unrecognized,
mavpackettype: "MISSION_ITEM_INT",
@@ -390,11 +401,11 @@ export default function Missions() {
)
}
- if (activeTab === "mission") {
+ if (activeTabRef.current === "mission") {
setMissionItems((prevItems) => getUpdatedItems(prevItems))
- } else if (activeTab === "fence") {
+ } else if (activeTabRef.current === "fence") {
setFenceItems((prevItems) => getUpdatedItems(prevItems))
- } else if (activeTab === "rally") {
+ } else if (activeTabRef.current === "rally") {
setRallyItems((prevItems) => getUpdatedItems(prevItems))
}
}
@@ -409,11 +420,11 @@ export default function Missions() {
}))
}
- if (activeTab === "mission") {
+ if (activeTabRef.current === "mission") {
setMissionItems((prevItems) => getUpdatedItems(prevItems))
- } else if (activeTab === "fence") {
+ } else if (activeTabRef.current === "fence") {
setFenceItems((prevItems) => getUpdatedItems(prevItems))
- } else if (activeTab === "rally") {
+ } else if (activeTabRef.current === "rally") {
setRallyItems((prevItems) => getUpdatedItems(prevItems))
}
}
@@ -451,39 +462,39 @@ export default function Missions() {
return updatedItems
}
- if (activeTab === "mission") {
+ if (activeTabRef.current === "mission") {
setMissionItems((prevItems) => updateItemOrder(prevItems))
- } else if (activeTab === "fence") {
+ } else if (activeTabRef.current === "fence") {
setFenceItems((prevItems) => updateItemOrder(prevItems))
}
}
function readMissionFromDrone() {
- socket.emit("get_current_mission", { type: activeTab })
- setMissionProgressModalTitle(`Reading ${activeTab} from drone`)
+ socket.emit("get_current_mission", { type: activeTabRef.current })
+ setMissionProgressModalTitle(`Reading ${activeTabRef.current} from drone`)
resetMissionProgressModalData()
openMissionProgressModal()
}
function writeMissionToDrone() {
- if (activeTab === "mission") {
+ if (activeTabRef.current === "mission") {
socket.emit("write_current_mission", {
type: "mission",
items: missionItems,
})
- } else if (activeTab === "fence") {
+ } else if (activeTabRef.current === "fence") {
socket.emit("write_current_mission", { type: "fence", items: fenceItems })
- } else if (activeTab === "rally") {
+ } else if (activeTabRef.current === "rally") {
socket.emit("write_current_mission", { type: "rally", items: rallyItems })
}
- setMissionProgressModalTitle(`Writing ${activeTab} to drone`)
+ setMissionProgressModalTitle(`Writing ${activeTabRef.current} to drone`)
resetMissionProgressModalData()
openMissionProgressModal()
}
function importMissionFromFile(filePath) {
socket.emit("import_mission_from_file", {
- type: activeTab,
+ type: activeTabRef.current,
file_path: filePath,
})
@@ -506,9 +517,9 @@ export default function Missions() {
if (!result.canceled) {
let items = []
- if (activeTab === "mission") {
+ if (activeTabRef.current === "mission") {
items = [...missionItems]
- } else if (activeTab === "fence") {
+ } else if (activeTabRef.current === "fence") {
items = [...fenceItems]
const newHomeItem = createHomePositionItem()
@@ -521,7 +532,7 @@ export default function Missions() {
...item,
seq: index,
}))
- } else if (activeTab === "rally") {
+ } else if (activeTabRef.current === "rally") {
items = [...rallyItems]
const newHomeItem = createHomePositionItem()
@@ -537,7 +548,7 @@ export default function Missions() {
}
socket.emit("export_mission_to_file", {
- type: activeTab,
+ type: activeTabRef.current,
file_path: result.filePath,
items: items,
})
@@ -592,7 +603,7 @@ export default function Missions() {
}
function clearMissionItems() {
- if (activeTab === "mission") {
+ if (activeTabRef.current === "mission") {
// Clear all mission items except the first if the first is a home position
if (
missionItems.length > 0 &&
@@ -602,9 +613,9 @@ export default function Missions() {
} else {
setMissionItems([])
}
- } else if (activeTab === "fence") {
+ } else if (activeTabRef.current === "fence") {
setFenceItems([])
- } else if (activeTab === "rally") {
+ } else if (activeTabRef.current === "rally") {
setRallyItems([])
}
}