Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/src/api/missions.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export const startMission = async (id: number, time: string) => {
headers: { 'Content-Type': 'application/json' },
},
);
return response.data as { message: string };
return response;
};

export const endMission = async (id: number, time: string) => {
Expand Down
19 changes: 16 additions & 3 deletions client/src/app/missions/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,22 @@ export default function MissionDetail() {
console.log('Updating mission:', id);

if (start) {

try {
// Push update to the database
const response = start
? await startMission(missionId, time)
: await endMission(missionId, time);

if (response.status == 200) {
console.log("mission " + missionId + " sent: " + response.data.message);
}

} catch (error) {
alert(`Mission failed to start: ${error.response?.data?.error || error.message}`);
return;
}

mission!.timeStart = time;
} else if (!start) {
mission!.timeEnd = time;
Expand All @@ -49,9 +65,6 @@ export default function MissionDetail() {
}
setMission(mission!);

// Push update to the database
const response = await (start ? startMission(missionId, time) : endMission(missionId, time));
console.log(`Mission ${start ? 'started' : 'ended'}:`, response);
};

const handleDelete = async (missionId: number, missionName: string) => {
Expand Down
2 changes: 1 addition & 1 deletion server/src/controllers/mission.controller.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export async function getMissionByIdController(req, res) {
res.status(500).json({ error: error.message });
}
}

// call mavlink sendmission corrdinaytion in this method
export async function createMissionController(req, res) {
try {
const body = req.body || {};
Expand Down
56 changes: 53 additions & 3 deletions server/src/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import express from 'express';
import cors from 'cors';
import { createServer } from 'http';
import { Server } from 'socket.io';

import { sendMissionCoordinates, handleMavlinkData } from "./services/mavlink.service.mjs";
import { serverConfig } from './config/server.config.mjs';
import missionRoutes from './routes/mission.routes.js';
import botRoutes from './routes/bot.routes.mjs';
Expand All @@ -21,6 +21,12 @@ const io = new Server(httpServer, {
}
});







// Middleware
app.use(cors({
origin: serverConfig.corsOrigin,
Expand All @@ -34,19 +40,63 @@ app.use('/api/missions', missionRoutes);
app.use('/api/bots', botRoutes);
app.use('/api/temperature', temperatureRoutes);


// ================= ROUTES =================

app.post('/api/send-coordinates', async (req, res) => {
try {
let coords = req.body;

if (!coords || Object.keys(coords).length === 0) {
console.log("No coordinates provided. Generating random test coordinates...");

coords = {
lat1: 499394300,
lon1: -1193964200,
lat2: 499394500,
lon2: -1193964500,
lat3: 499394700,
lon3: -1193964300,
lat4: 499394900,
lon4: -1193964700
};
}
botID = 1;
console.log("Website requested send-coordinates (botID = 1):");
console.log(coords);

await sendMissionCoordinates(botID, coords);

return res.status(200).json({
success: true,
message: "Mission coordinates successfully sent to robot.",
sent: coords
});

} catch (error) {
console.error("Error sending coordinates:", error);
return res.status(500).json({ error: "Failed to send mission coordinates." });
}
});



// Setup Socket.IO handlers
setupSocketHandlers(io);

// Setup MAVLink data handler with io context
setStoreMavlinkDataCallback((data) => storeMavlinkData(data, io));

// Start MAVLink data simulation
// handleMavlinkData(); // for real data
simulateMavlinkData(); // for simulated data
handleMavlinkData(); // for real data
// simulateMavlinkData(); // for simulated data


// Start server
httpServer.listen(serverConfig.port, () => {
console.log(`Server running on port ${serverConfig.port}`);
console.log(`WebSocket server ready`);
console.log(`Environment: ${serverConfig.environment}`);
});


38 changes: 38 additions & 0 deletions server/src/services/database.service.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { pool } from '../config/database.config.mjs';
import assert from 'assert';
import { sendMissionCoordinates } from "./mavlink.service.mjs";

// Helper to parse JSON columns safely
const parseJSON = (value, fallback = null) => {
Expand Down Expand Up @@ -378,6 +379,43 @@ export async function startMission(missionId, startTime, bots) {
`UPDATE bot SET assignmentStatus = 'active' WHERE botID IN (${bots.map(() => '?').join(',')})`,
bots
);

// 1. Get the assigned botIDs
const botIDs = await getAssignmentsForMission(missionId);


if (!botIDs || botIDs.length === 0) {
return { success: true }; // nothing to send
}

// 2. Get mission data
const missionResult = await getMissionByID(missionId);
if (!missionResult.success) {
throw new Error("Mission not found");
}

const mission = missionResult.data;

// Parse coordinates safely
const area = parseJSON(mission.areaCoordinates);

if (!area) {
throw new Error("Invalid areaCoordinates");
}

// 3. Construct coords object (4 corners)
const coords = {
lat1: area.north, lon1: area.west, // top-left
lat2: area.north, lon2: area.east, // top-right
lat3: area.south, lon3: area.east, // bottom-right
lat4: area.south, lon4: area.west // bottom-left
};

// 4. Send to each bot
for (const botID of botIDs) {
await sendMissionCoordinates(botID, coords);
}

return { success: true };
} catch (error) {
console.error('Error starting mission:', error);
Expand Down
Loading