Skip to content

Commit 3d09b7d

Browse files
committed
Alpha 0.1.10/592 add rally point functionality to missions (#599)
* Start adding rally functionality to missions page * Finish adding rally point functionality * Address copilot comments
1 parent 5fe1378 commit 3d09b7d

4 files changed

Lines changed: 127 additions & 28 deletions

File tree

gcs/src/components/missions/missionsMap.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ function MapSectionNonMemo({
5252
getFlightMode,
5353
currentTab,
5454
markerDragEndCallback,
55-
rallyDragEndCallback,
5655
addNewMissionItem,
5756
updateMissionHomePosition,
5857
mapId = "dashboard",
@@ -267,9 +266,10 @@ function MapSectionNonMemo({
267266
lat={intToCoord(item.x)}
268267
lon={intToCoord(item.y)}
269268
colour={tailwindColors.purple[400]}
269+
text={`${item.seq}`}
270270
tooltipText={item.z ? `Alt: ${item.z}` : null}
271271
draggable={currentTab === "rally"}
272-
dragEndCallback={rallyDragEndCallback}
272+
dragEndCallback={markerDragEndCallback}
273273
/>
274274
)
275275
})}

gcs/src/components/missions/rallyItemsTable.jsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import { Table } from "@mantine/core"
55
import React from "react"
66
import RallyItemsTableRow from "./rallyItemsTableRow"
77

8-
function RallyItemsTableNonMemo({ rallyItems, updateRallyItem }) {
8+
function RallyItemsTableNonMemo({
9+
rallyItems,
10+
updateRallyItem,
11+
deleteRallyItem,
12+
}) {
913
return (
1014
<Table striped withTableBorder withColumnBorders stickyHeader>
1115
<Table.Thead>
@@ -20,6 +24,7 @@ function RallyItemsTableNonMemo({ rallyItems, updateRallyItem }) {
2024
<Table.Th>Lng</Table.Th>
2125
<Table.Th>Alt</Table.Th>
2226
<Table.Th>Frame</Table.Th>
27+
<Table.Th></Table.Th>
2328
</Table.Tr>
2429
</Table.Thead>
2530
<Table.Tbody>
@@ -30,6 +35,7 @@ function RallyItemsTableNonMemo({ rallyItems, updateRallyItem }) {
3035
index={idx}
3136
rallyItem={rallyItem}
3237
updateRallyItem={updateRallyItem}
38+
deleteRallyItem={deleteRallyItem}
3339
/>
3440
)
3541
})}

gcs/src/components/missions/rallyItemsTableRow.jsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@
22
This component displays the row for a rally item in a table.
33
*/
44

5-
import { NumberInput, Select, TableTd, TableTr } from "@mantine/core"
5+
import {
6+
ActionIcon,
7+
NumberInput,
8+
Select,
9+
TableTd,
10+
TableTr,
11+
} from "@mantine/core"
12+
import { IconTrash } from "@tabler/icons-react"
613
import { useEffect, useState } from "react"
714
import { coordToInt, intToCoord } from "../../helpers/dataFormatters"
815
import { MAV_FRAME_LIST } from "../../helpers/mavlinkConstants"
@@ -12,6 +19,7 @@ export default function RallyItemsTableRow({
1219
index,
1320
rallyItem,
1421
updateRallyItem,
22+
deleteRallyItem,
1523
}) {
1624
const [rallyItemData, setRallyItemData] = useState(rallyItem)
1725

@@ -85,6 +93,14 @@ export default function RallyItemsTableRow({
8593
/>
8694
</TableTd>
8795
<TableTd>{getFrameName(rallyItemData.frame)}</TableTd>
96+
<TableTd>
97+
<ActionIcon
98+
onClick={() => deleteRallyItem(rallyItemData.id)}
99+
color="red"
100+
>
101+
<IconTrash size={20} />
102+
</ActionIcon>
103+
</TableTd>
88104
</TableTr>
89105
)
90106
}

gcs/src/missions.jsx

Lines changed: 101 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ export default function Missions() {
177177
for (let rallyItem of data.items) {
178178
rallyItemsWithIds.push(addIdToItem(rallyItem))
179179
}
180+
180181
setRallyItems(rallyItemsWithIds)
181182
}
182183
showSuccessNotification(data.message)
@@ -257,7 +258,7 @@ export default function Missions() {
257258
function addNewMissionItem(lat, lon) {
258259
const newMissionItem = {
259260
id: uuidv4(),
260-
seq: missionItems.length,
261+
seq: null,
261262
x: coordToInt(lat),
262263
y: coordToInt(lon),
263264
z: newMissionItemAltitude,
@@ -266,7 +267,7 @@ export default function Missions() {
266267
(key) => MAV_FRAME_LIST[key] === "MAV_FRAME_GLOBAL_RELATIVE_ALT",
267268
),
268269
),
269-
command: 16, // MAV_CMD_NAV_WAYPOINT
270+
command: null,
270271
param1: 0,
271272
param2: 0,
272273
param3: 0,
@@ -275,41 +276,106 @@ export default function Missions() {
275276
autocontinue: 1,
276277
target_component: targetInfo.target_component,
277278
target_system: targetInfo.target_system,
278-
mission_type: 0,
279+
mission_type: null,
280+
mavpackettype: "MISSION_ITEM_INT",
281+
}
282+
283+
if (activeTab === "mission") {
284+
newMissionItem.seq = missionItems.length
285+
newMissionItem.command = 16 // MAV_CMD_NAV_WAYPOINT
286+
newMissionItem.mission_type = 0 // Mission type
287+
288+
setMissionItems((prevItems) => [...prevItems, newMissionItem])
289+
} else if (activeTab === "fence") {
290+
newMissionItem.seq = fenceItems.length
291+
newMissionItem.command = 5100 // MAV_CMD_NAV_FENCE_POINT
292+
newMissionItem.mission_type = 1 // Fence type
293+
294+
setFenceItems((prevItems) => [...prevItems, newMissionItem])
295+
} else if (activeTab === "rally") {
296+
newMissionItem.seq = rallyItems.length
297+
newMissionItem.command = 5100 // MAV_CMD_NAV_RALLY_POINT
298+
newMissionItem.mission_type = 2 // Rally type
299+
300+
setRallyItems((prevItems) => [...prevItems, newMissionItem])
301+
}
302+
}
303+
304+
function createHomePositionItem() {
305+
if (!homePosition) {
306+
showErrorNotification("Home position is not set")
307+
return
308+
}
309+
310+
const newHomeItem = {
311+
id: uuidv4(),
312+
seq: 0, // Home position is always the first item
313+
x: homePosition.lat,
314+
y: homePosition.lon,
315+
z: homePosition.alt || 0,
316+
frame: parseInt(
317+
Object.keys(MAV_FRAME_LIST).find(
318+
(key) => MAV_FRAME_LIST[key] === "MAV_FRAME_GLOBAL",
319+
),
320+
),
321+
command: 16, // MAV_CMD_NAV_WAYPOINT
322+
param1: 0,
323+
param2: 0,
324+
param3: 0,
325+
param4: 0,
326+
current: 1, // Set as current waypoint
327+
autocontinue: 1,
328+
target_component: targetInfo.target_component,
329+
target_system: targetInfo.target_system,
330+
mission_type:
331+
activeTab === "mission"
332+
? 0
333+
: activeTab === "fence"
334+
? 1
335+
: activeTab === "rally"
336+
? 2
337+
: 0, // Default to 0 (Mission type) if activeTab is unrecognized,
279338
mavpackettype: "MISSION_ITEM_INT",
280339
}
281340

282-
setMissionItems((prevItems) => [...prevItems, newMissionItem])
341+
return newHomeItem
283342
}
284343

285344
function updateMissionItem(updatedMissionItem) {
286-
setMissionItems((prevItems) =>
287-
prevItems.map((item) =>
345+
function getUpdatedItems(prevItems) {
346+
return prevItems.map((item) =>
288347
item.id === updatedMissionItem.id
289348
? { ...item, ...updatedMissionItem }
290349
: item,
291-
),
292-
)
293-
}
294-
function updateRallyItem(updatedRallyItem) {
295-
setRallyItems((prevItems) =>
296-
prevItems.map((item) =>
297-
item.id === updatedRallyItem.id
298-
? { ...item, ...updatedRallyItem }
299-
: item,
300-
),
301-
)
350+
)
351+
}
352+
353+
if (activeTab === "mission") {
354+
setMissionItems((prevItems) => getUpdatedItems(prevItems))
355+
} else if (activeTab === "fence") {
356+
// TODO: Implement fence item update logic
357+
} else if (activeTab === "rally") {
358+
setRallyItems((prevItems) => getUpdatedItems(prevItems))
359+
}
302360
}
303361

304362
function deleteMissionItem(missionItemId) {
305-
setMissionItems((prevItems) => {
363+
function getUpdatedItems(prevItems) {
306364
const updatedItems = prevItems.filter((item) => item.id !== missionItemId)
307365

308366
return updatedItems.map((item, index) => ({
309367
...item,
310368
seq: index, // Reassign seq based on the new order
311369
}))
312-
})
370+
}
371+
372+
if (activeTab === "mission") {
373+
setMissionItems((prevItems) => getUpdatedItems(prevItems))
374+
} else if (activeTab === "fence") {
375+
// TODO: Implement fence item deletion logic
376+
} else if (activeTab === "rally") {
377+
setRallyItems((prevItems) => getUpdatedItems(prevItems))
378+
}
313379
}
314380

315381
function updateMissionItemOrder(missionItemId, indexIncrement) {
@@ -389,11 +455,22 @@ export default function Missions() {
389455
if (!result.canceled) {
390456
let items = []
391457
if (activeTab === "mission") {
392-
items = missionItems
458+
items = [...missionItems]
393459
} else if (activeTab === "fence") {
394-
items = fenceItems
460+
items = [...fenceItems]
395461
} else if (activeTab === "rally") {
396-
items = rallyItems
462+
items = [...rallyItems]
463+
464+
const newHomeItem = createHomePositionItem()
465+
if (newHomeItem) {
466+
items.unshift(newHomeItem) // Add home item at the beginning
467+
}
468+
469+
// Ensure all sequence values are updated
470+
items = items.map((item, index) => ({
471+
...item,
472+
seq: index,
473+
}))
397474
}
398475

399476
socket.emit("export_mission_to_file", {
@@ -565,7 +642,6 @@ export default function Missions() {
565642
getFlightMode={getFlightMode}
566643
currentTab={activeTab}
567644
markerDragEndCallback={updateMissionItem}
568-
rallyDragEndCallback={updateRallyItem}
569645
addNewMissionItem={addNewMissionItem}
570646
updateMissionHomePosition={updateMissionHomePosition}
571647
mapId="missions"
@@ -609,7 +685,8 @@ export default function Missions() {
609685
<Tabs.Panel value="rally">
610686
<RallyItemsTable
611687
rallyItems={rallyItems}
612-
updateRallyItem={updateRallyItem}
688+
updateRallyItem={updateMissionItem}
689+
deleteRallyItem={deleteMissionItem}
613690
/>
614691
</Tabs.Panel>
615692
</Tabs>

0 commit comments

Comments
 (0)