From 12f9ecbf4f59f65be4d4296cd7ab452198bc70e1 Mon Sep 17 00:00:00 2001 From: codemaster1104 Date: Sun, 23 Mar 2025 23:15:31 +0530 Subject: [PATCH 1/3] corrected message handling --- Chat/index.html | 144 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 129 insertions(+), 15 deletions(-) diff --git a/Chat/index.html b/Chat/index.html index 8c5c5dbf..32d80283 100644 --- a/Chat/index.html +++ b/Chat/index.html @@ -96,7 +96,7 @@

Chat

@@ -116,6 +116,8 @@

Chat

// imports import { mavlink_store } from './MAVLink/mavlink_store.js'; + let latest_heartbeat_message = null; + // show/hide the OpenAI API key field function toggle_openai_api_key_visibility() { let openai_key_input = document.getElementById("openai_api_key"); @@ -179,24 +181,99 @@

Chat

mavlink_disconnect(); }; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // parse incoming message and forward mavlink_ws.onmessage = (msg) => { // sanity check parser has been created if (MAVLink == null) { return; } + // add_text_to_debug(msg.data); + + const json_data = JSON.parse(msg.data); + // add_text_to_debug("Received: " + json_data.mavpackettype); + const mavlink_msg = createMavlinkMsgFromJson(json_data); + // parse message - for (const char of new Uint8Array(msg.data)) { - const mavlink_msg = MAVLink.parseChar(char) - if ((mavlink_msg != null) && (mavlink_msg._id != -1)) { - // got a message with a known ID - mavlink_msg_handler(mavlink_msg); - } + if (mavlink_msg) { + mavlink_msg_handler(mavlink_msg); + // add_text_to_debug("done and dusted"); + } + else add_text_to_debug("❌❌❌❌no msg"); + + } + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + } + } + + // Add this function to convert JSON to MAVLink-compatible format + function createMavlinkMsgFromJson(json) { + if (!json || !json.mavpackettype) { + add_text_to_debug("❌ Invalid message format"); + return null; + } + + try { + // Create a base object that preserves all original fields + const result = { + ...json, + // Add required fields for mavlink_store + _id: getMavlinkMessageId(json.mavpackettype), + _header: { + srcSystem: 1, // Default system ID + srcComponent: 1 // Default component ID } + }; + + // Special handling for HEARTBEAT messages + if (json.mavpackettype === "HEARTBEAT") { + // add_text_to_debug("⭐ Received heartbeat message"); + // Store directly for quick access + latest_heartbeat_message = result; } + + return result; + } catch (error) { + add_text_to_debug("❌ Error creating MAVLink message: " + error.message); + return null; } } + // Helper function to map common message types to IDs + function getMavlinkMessageId(msgType) { + if (msgType.toUpperCase() === "HEARTBEAT") { + return 0; // Always use 0 for HEARTBEAT + } + const messageMap = { + "HEARTBEAT": 0, + "heartbeat": 0, + "SYS_STATUS": 1, + "PARAM_VALUE": 22, + "GPS_RAW_INT": 24, + "ATTITUDE": 30, + "GLOBAL_POSITION_INT": 33, + "RC_CHANNELS_RAW": 35, + "SERVO_OUTPUT_RAW": 36, + "MISSION_ITEM": 39, + "MISSION_REQUEST": 40, + "MISSION_ACK": 47, + "GPS_GLOBAL_ORIGIN": 49, + "NAV_CONTROLLER_OUTPUT": 62, + "RC_CHANNELS": 65, + "VFR_HUD": 74, + "COMMAND_LONG": 76, + "COMMAND_ACK": 77, + "ATTITUDE_QUATERNION": 31, + "LOCAL_POSITION_NED": 32, + "POSITION_TARGET_LOCAL_NED": 85, + "POSITION_TARGET_GLOBAL_INT": 87, + "STATUSTEXT": 253 + }; + + return messageMap[msgType] || -1; // Return -1 for unknown types + } // disconnect from the vehicle function mavlink_disconnect() { if (mavlink_ws != null) { @@ -213,25 +290,27 @@

Chat

return; } + // store the message in the message store mavlink_store.store_message(msg); switch (msg._id) { case 0: // HEARTBEAT - //alert("custom mode:" + msg.custom_mode); - //alert("Got a heartbeat: " + JSON.stringify(msg)); + // alert("custom mode:" + msg.custom_mode); + // add_text_to_debug("HEARTBEAT message processed in switch statement!"); + // alert("Got a heartbeat: " + JSON.stringify(msg)); break; case 1: // SYS_STATUS - //alert("Got a system status: " + JSON.stringify(msg)); + // alert("Got a system status: " + JSON.stringify(msg)); break; case 24: // GPS_RAW_INT //alert("Got a GPS raw int: " + JSON.stringify(msg)); break; case 30: // ATTITUDE - //alert("Got an attitude: " + JSON.stringify(msg)); + // alert("Got an attitude: " + JSON.stringify(msg)); break; case 33: // GLOBAL_POSITION_INT - //alert("Got a global position int: " + JSON.stringify(msg)); + // alert("Got a global position int: " + JSON.stringify(msg)); break; case 35: // HIGHRES_IMU //alert("Got a high resolution IMU: " + JSON.stringify(msg)); @@ -246,7 +325,7 @@

Chat

//alert("Got a status text: " + JSON.stringify(msg)); break; default: - //alert("Got a message id: " + JSON.stringify(msg)); + // alert("Got a message id: " + JSON.stringify(msg)); break; } } @@ -518,7 +597,7 @@

Chat

// fallthrough case "get_vehicle_location_and_yaw": // Get the vehicle's current location including latitude, longitude, altitude above sea level and altitude above home - // fallthrough + return get_vehicle_location_and_yaw(); case "send_mavlink_set_position_target_global_int": // Send a mavlink SET_POSITION_TARGET_GLOBAL_INT message to the vehicle. This message is the preferred way to command a vehicle to fly to a specified location or to fly at a specfied velocity // fallthrough @@ -528,6 +607,7 @@

Chat

case "get_location_plus_offset": // Calculate the latitude and longitude given an existing latitude and longitude and distances (in meters) North and East // fallthrough + // return get_location_plus_offset(); case "send_mavlink_command_int": // Send a mavlink COMMAND_INT message to the vehicle. Available commands including changing the flight mode, arming, disarming, takeoff and commanding the vehicle to fly to a specific location // fallthrough @@ -641,6 +721,40 @@

Chat

return new Date().toLocaleString('en-US', options); } + function get_vehicle_location_and_yaw() { + // Get the latest GLOBAL_POSITION_INT message + const position_msg = mavlink_store.get_latest_message(33); + add_text_to_debug(position_msg); + if (!position_msg) { + return JSON.stringify({ + error: "No position information available" + }); + } + + // Get the latest ATTITUDE message for yaw (if available) + const attitude_msg = mavlink_store.get_latest_message(30); + + // Convert lat/lon from int32 (degE7) to decimal degrees + const lat = position_msg.lat / 10000000.0; + const lon = position_msg.lon / 10000000.0; + + // Create the response object + const response = { + latitude: lat, + longitude: lon, + altitude_msl: position_msg.alt / 1000.0, // mm to meters + altitude_relative: position_msg.relative_alt / 1000.0, // mm to meters + heading: position_msg.hdg / 100.0 // centi-degrees to degrees + }; + + // Add attitude information if available + if (attitude_msg) { + response.yaw = attitude_msg.yaw * (180 / Math.PI); // radians to degrees + } + + return JSON.stringify(response); +} + class EventHandler extends EventEmitter { constructor(client) { super() @@ -746,4 +860,4 @@

Chat

} - + \ No newline at end of file From 00429a54748db33218c0ae3193ff13f4bd902576 Mon Sep 17 00:00:00 2001 From: codemaster1104 Date: Mon, 11 Aug 2025 21:41:50 +0530 Subject: [PATCH 2/3] update --- Chat/i2.html | 1226 ++++++++++++++++++++++++++++++++ Chat/i3.html | 1801 +++++++++++++++++++++++++++++++++++++++++++++++ Chat/index.html | 283 ++++---- 3 files changed, 3183 insertions(+), 127 deletions(-) create mode 100644 Chat/i2.html create mode 100644 Chat/i3.html diff --git a/Chat/i2.html b/Chat/i2.html new file mode 100644 index 00000000..eb5edb2f --- /dev/null +++ b/Chat/i2.html @@ -0,0 +1,1226 @@ + + + + + Chat + + + + + + + + +
+ + +
+ +
+ + + +

Chat

+ + +
+
+
+ + + +
+
+ + +
+ + + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + + + + + + + +
+ +
+ + + + + + + \ No newline at end of file diff --git a/Chat/i3.html b/Chat/i3.html new file mode 100644 index 00000000..0c3b68e0 --- /dev/null +++ b/Chat/i3.html @@ -0,0 +1,1801 @@ + + + + + Chat + + + + + + + + +
+ + +
+ +
+ + + +

Chat

+ + +
+
+
+ + + +
+
+ + +
+ + + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + + + + + + + + + + +
+ +
+ + + + + + + diff --git a/Chat/index.html b/Chat/index.html index 32d80283..df69f46e 100644 --- a/Chat/index.html +++ b/Chat/index.html @@ -64,7 +64,7 @@

Chat

- +
@@ -96,7 +96,7 @@

Chat

@@ -173,6 +173,7 @@

Chat

// set up event handlers mavlink_ws.onopen = function() { mavlink_set_connect_state(true); + add_text_to_debug("WebSocket CONNECTED successfully!"); }; mavlink_ws.onclose = function() { mavlink_set_connect_state(false); @@ -181,99 +182,103 @@

Chat

mavlink_disconnect(); }; + // Replace your onmessage handler with this for better debugging: + // mavlink_ws.onmessage = (msg) => { + + // if (MAVLink == null) { + // return; + // } + + // // Debug data type + // // add_text_to_debug("⚡ Received data type: " + typeof(msg.data)); + // // add_text_to_debug("msg is: "+msg.data); + + // // Handle different data types + // let dataArray; + // if (typeof msg.data === 'string') { + // // add_text_to_debug("String data received - converting to bytes"); + // // dataArray = new TextEncoder().encode(msg.data); + + // for (const char of new Uint8Array(msg.data)) { + // add_text_to_debug("1"); + // const mavlink_msg = MAVLink.parseChar(char) + // add_text_to_debug("2"); + // if ((mavlink_msg != null) && (mavlink_msg._id != -1)) { + // // got a message with a known ID + // add_text_to_debug("3"); + // mavlink_msg_handler(mavlink_msg); + // add_text_to_debug("yayyy"); + // } + // } + + // } else if (msg.data instanceof ArrayBuffer) { + // dataArray = new Uint8Array(msg.data); + // } else if (msg.data instanceof Blob) { + // add_text_to_debug("Blob data received - reading as ArrayBuffer"); + // // Need to read the Blob asynchronously + // const reader = new FileReader(); + // reader.onload = function() { + // const arrayBuffer = reader.result; + // const bytes = new Uint8Array(arrayBuffer); + // processMavlinkBytes(bytes); + // }; + // reader.readAsArrayBuffer(msg.data); + // return; + // } else { + // add_text_to_debug("❌ Unknown data type received"); + // return; + // } + + // // processMavlinkBytes(dataArray); + // }; - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // parse incoming message and forward mavlink_ws.onmessage = (msg) => { - // sanity check parser has been created if (MAVLink == null) { return; } - // add_text_to_debug(msg.data); - - const json_data = JSON.parse(msg.data); - // add_text_to_debug("Received: " + json_data.mavpackettype); - const mavlink_msg = createMavlinkMsgFromJson(json_data); - // parse message - if (mavlink_msg) { - mavlink_msg_handler(mavlink_msg); - // add_text_to_debug("done and dusted"); + // Debug data type + // add_text_to_debug("Received data of type: " + typeof(msg.data)); + + let dataArray; + if (typeof msg.data === 'string') { + // Properly convert string to bytes + // add_text_to_debug("Converting string data to bytes"); + const encoder = new TextEncoder(); + dataArray = encoder.encode(msg.data); + } else if (msg.data instanceof ArrayBuffer) { + dataArray = new Uint8Array(msg.data); + } else if (msg.data instanceof Blob) { + // Handle asynchronously + const reader = new FileReader(); + reader.onload = function() { + processMavlinkBytes(new Uint8Array(reader.result)); + }; + reader.readAsArrayBuffer(msg.data); + return; + } else { + add_text_to_debug("❌ Unknown data type received"); + return; } - else add_text_to_debug("❌❌❌❌no msg"); - } - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - } - } + // Process the bytes + processMavlinkBytes(dataArray); + }; - // Add this function to convert JSON to MAVLink-compatible format - function createMavlinkMsgFromJson(json) { - if (!json || !json.mavpackettype) { - add_text_to_debug("❌ Invalid message format"); - return null; - } - - try { - // Create a base object that preserves all original fields - const result = { - ...json, - // Add required fields for mavlink_store - _id: getMavlinkMessageId(json.mavpackettype), - _header: { - srcSystem: 1, // Default system ID - srcComponent: 1 // Default component ID + function processMavlinkBytes(bytes) { + // add_text_to_debug("Processing " + bytes.length + " bytes"); + for (const byte of bytes) { + const mavlink_msg = MAVLink.parseChar(byte); + if (mavlink_msg && mavlink_msg._id !== -1) { + // add_text_to_debug("Parsed message ID: " + mavlink_msg._id); + mavlink_msg_handler(mavlink_msg); + } } - }; - - // Special handling for HEARTBEAT messages - if (json.mavpackettype === "HEARTBEAT") { - // add_text_to_debug("⭐ Received heartbeat message"); - // Store directly for quick access - latest_heartbeat_message = result; } - - return result; - } catch (error) { - add_text_to_debug("❌ Error creating MAVLink message: " + error.message); - return null; - } - } - // Helper function to map common message types to IDs - function getMavlinkMessageId(msgType) { - if (msgType.toUpperCase() === "HEARTBEAT") { - return 0; // Always use 0 for HEARTBEAT } - const messageMap = { - "HEARTBEAT": 0, - "heartbeat": 0, - "SYS_STATUS": 1, - "PARAM_VALUE": 22, - "GPS_RAW_INT": 24, - "ATTITUDE": 30, - "GLOBAL_POSITION_INT": 33, - "RC_CHANNELS_RAW": 35, - "SERVO_OUTPUT_RAW": 36, - "MISSION_ITEM": 39, - "MISSION_REQUEST": 40, - "MISSION_ACK": 47, - "GPS_GLOBAL_ORIGIN": 49, - "NAV_CONTROLLER_OUTPUT": 62, - "RC_CHANNELS": 65, - "VFR_HUD": 74, - "COMMAND_LONG": 76, - "COMMAND_ACK": 77, - "ATTITUDE_QUATERNION": 31, - "LOCAL_POSITION_NED": 32, - "POSITION_TARGET_LOCAL_NED": 85, - "POSITION_TARGET_GLOBAL_INT": 87, - "STATUSTEXT": 253 - }; - - return messageMap[msgType] || -1; // Return -1 for unknown types } + // disconnect from the vehicle function mavlink_disconnect() { if (mavlink_ws != null) { @@ -290,27 +295,31 @@

Chat

return; } + // Store directly if this is a heartbeat message + if (msg._id === 0) { // HEARTBEAT + latest_heartbeat_message = msg; + add_text_to_debug("⭐ Stored heartbeat directly: type=" + msg.type); + } - // store the message in the message store + // Still store in mavlink_store for other functions mavlink_store.store_message(msg); switch (msg._id) { case 0: // HEARTBEAT - // alert("custom mode:" + msg.custom_mode); - // add_text_to_debug("HEARTBEAT message processed in switch statement!"); - // alert("Got a heartbeat: " + JSON.stringify(msg)); + //alert("custom mode:" + msg.custom_mode); + //alert("Got a heartbeat: " + JSON.stringify(msg)); break; case 1: // SYS_STATUS - // alert("Got a system status: " + JSON.stringify(msg)); + //alert("Got a system status: " + JSON.stringify(msg)); break; case 24: // GPS_RAW_INT //alert("Got a GPS raw int: " + JSON.stringify(msg)); break; case 30: // ATTITUDE - // alert("Got an attitude: " + JSON.stringify(msg)); + //alert("Got an attitude: " + JSON.stringify(msg)); break; case 33: // GLOBAL_POSITION_INT - // alert("Got a global position int: " + JSON.stringify(msg)); + //alert("Got a global position int: " + JSON.stringify(msg)); break; case 35: // HIGHRES_IMU //alert("Got a high resolution IMU: " + JSON.stringify(msg)); @@ -325,7 +334,7 @@

Chat

//alert("Got a status text: " + JSON.stringify(msg)); break; default: - // alert("Got a message id: " + JSON.stringify(msg)); + //alert("Got a message id: " + JSON.stringify(msg)); break; } } @@ -366,6 +375,7 @@

Chat

debugOutput.value += text + "\n"; debugOutput.scrollTop = debugOutput.scrollHeight; } + - - - - - - -
- - -
- -
- - - -

Chat

- - -
-
-
- - - -
-
- - -
- - - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - - - - -
- -
- - - - - - - \ No newline at end of file diff --git a/Chat/i3.html b/Chat/i3.html deleted file mode 100644 index 0c3b68e0..00000000 --- a/Chat/i3.html +++ /dev/null @@ -1,1801 +0,0 @@ - - - - - Chat - - - - - - - - -
- - -
- -
- - - -

Chat

- - -
-
-
- - - -
-
- - -
- - - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - - - - - - - -
- -
- - - - - - - diff --git a/Chat/index.html b/Chat/index.html index df69f46e..0c3b68e0 100644 --- a/Chat/index.html +++ b/Chat/index.html @@ -64,7 +64,7 @@

Chat

- +
@@ -96,7 +96,7 @@

Chat

@@ -106,6 +106,12 @@

Chat

+ + +
@@ -116,8 +122,6 @@

Chat

// imports import { mavlink_store } from './MAVLink/mavlink_store.js'; - let latest_heartbeat_message = null; - // show/hide the OpenAI API key field function toggle_openai_api_key_visibility() { let openai_key_input = document.getElementById("openai_api_key"); @@ -127,10 +131,14 @@

Chat

// MAVLink connection related functions let connect_button = document.getElementById("mavlink-connect-button"); let is_connected = false; // connection state - let mavlink_ws = null; // websocket object + // let mavlink_ws = null; // websocket object + let mavlink_sysid = 254; // system id let mavlink_compid = MAVLink20Processor.MAV_COMP_ID_MISSIONPLANNER; // component id - let MAVLink = new MAVLink20Processor(null, mavlink_sysid, mavlink_compid); + // let MAVLink = new MAVLink20Processor(null, mavlink_sysid, mavlink_compid); + + window.mavlink_ws = null; // Make them globally accessible + window.MAVLink = new MAVLink20Processor(null, mavlink_sysid, mavlink_compid); // toggle connection state (called by Connect/Disconnect button) function mavlink_toggle_connect() { @@ -173,7 +181,6 @@

Chat

// set up event handlers mavlink_ws.onopen = function() { mavlink_set_connect_state(true); - add_text_to_debug("WebSocket CONNECTED successfully!"); }; mavlink_ws.onclose = function() { mavlink_set_connect_state(false); @@ -182,100 +189,21 @@

Chat

mavlink_disconnect(); }; - // Replace your onmessage handler with this for better debugging: - // mavlink_ws.onmessage = (msg) => { - - // if (MAVLink == null) { - // return; - // } - - // // Debug data type - // // add_text_to_debug("⚡ Received data type: " + typeof(msg.data)); - // // add_text_to_debug("msg is: "+msg.data); - - // // Handle different data types - // let dataArray; - // if (typeof msg.data === 'string') { - // // add_text_to_debug("String data received - converting to bytes"); - // // dataArray = new TextEncoder().encode(msg.data); - - // for (const char of new Uint8Array(msg.data)) { - // add_text_to_debug("1"); - // const mavlink_msg = MAVLink.parseChar(char) - // add_text_to_debug("2"); - // if ((mavlink_msg != null) && (mavlink_msg._id != -1)) { - // // got a message with a known ID - // add_text_to_debug("3"); - // mavlink_msg_handler(mavlink_msg); - // add_text_to_debug("yayyy"); - // } - // } - - // } else if (msg.data instanceof ArrayBuffer) { - // dataArray = new Uint8Array(msg.data); - // } else if (msg.data instanceof Blob) { - // add_text_to_debug("Blob data received - reading as ArrayBuffer"); - // // Need to read the Blob asynchronously - // const reader = new FileReader(); - // reader.onload = function() { - // const arrayBuffer = reader.result; - // const bytes = new Uint8Array(arrayBuffer); - // processMavlinkBytes(bytes); - // }; - // reader.readAsArrayBuffer(msg.data); - // return; - // } else { - // add_text_to_debug("❌ Unknown data type received"); - // return; - // } - - // // processMavlinkBytes(dataArray); - // }; - + // parse incoming message and forward mavlink_ws.onmessage = (msg) => { + // sanity check parser has been created if (MAVLink == null) { return; } - - // Debug data type - // add_text_to_debug("Received data of type: " + typeof(msg.data)); - - let dataArray; - if (typeof msg.data === 'string') { - // Properly convert string to bytes - // add_text_to_debug("Converting string data to bytes"); - const encoder = new TextEncoder(); - dataArray = encoder.encode(msg.data); - } else if (msg.data instanceof ArrayBuffer) { - dataArray = new Uint8Array(msg.data); - } else if (msg.data instanceof Blob) { - // Handle asynchronously - const reader = new FileReader(); - reader.onload = function() { - processMavlinkBytes(new Uint8Array(reader.result)); - }; - reader.readAsArrayBuffer(msg.data); - return; - } else { - add_text_to_debug("❌ Unknown data type received"); - return; - } - - // Process the bytes - processMavlinkBytes(dataArray); - }; - - function processMavlinkBytes(bytes) { - // add_text_to_debug("Processing " + bytes.length + " bytes"); - for (const byte of bytes) { - const mavlink_msg = MAVLink.parseChar(byte); - if (mavlink_msg && mavlink_msg._id !== -1) { - // add_text_to_debug("Parsed message ID: " + mavlink_msg._id); + // parse message + for (const char of new Uint8Array(msg.data)) { + const mavlink_msg = MAVLink.parseChar(char) + if ((mavlink_msg != null) && (mavlink_msg._id != -1)) { + // got a message with a known ID mavlink_msg_handler(mavlink_msg); } } } - } } @@ -295,13 +223,7 @@

Chat

return; } - // Store directly if this is a heartbeat message - if (msg._id === 0) { // HEARTBEAT - latest_heartbeat_message = msg; - add_text_to_debug("⭐ Stored heartbeat directly: type=" + msg.type); - } - - // Still store in mavlink_store for other functions + // store the message in the message store mavlink_store.store_message(msg); switch (msg._id) { @@ -369,6 +291,41 @@

Chat

// attach event listener to the arm button document.getElementById("mavlink-arm-button").addEventListener("click", mavlink_arm_vehicle); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // switch to guided mode +function mavlink_switch_to_guided() { + if (mavlink_ws == null || mavlink_ws.readyState !== WebSocket.OPEN) { + alert("Please connect to the vehicle first"); + return; + } + + // Use command_long message for mode change (command 176: MAV_CMD_DO_SET_MODE) + let command_long_msg = new mavlink20.messages.command_long( + 1, // Target system ID + 1, // Target component ID + 176, // MAV_CMD_DO_SET_MODE + 1, // Confirmation + 1, // Param1: set to 1 for MAV_MODE_FLAG_CUSTOM_MODE_ENABLED + 4, // Param2: 4 is GUIDED mode for Copter + 0, 0, 0, 0, 0 // Unused parameters + ); + + const buffer = MAVLink.send(command_long_msg); + const uint = new Uint8Array(buffer); + + // send the message as an ArrayBuffer over the WebSocket + if (mavlink_ws && mavlink_ws.readyState === WebSocket.OPEN) { + mavlink_ws.send(uint); + add_text_to_debug("Sent GUIDED mode command via MAVLink"); + } else { + alert("WebSocket is not open. Cannot send GUIDED mode command."); + } +} +// attach event listener to the guided mode button +document.getElementById("mavlink-guided-button").addEventListener("click", mavlink_switch_to_guided); +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // add text to debug text box function add_text_to_debug(text) { let debugOutput = document.getElementById("debugOutput"); @@ -376,6 +333,73 @@

Chat

debugOutput.scrollTop = debugOutput.scrollHeight; } +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Global variable to store wakeup timers + const wakeup_timers = []; + + // Then implement set_wakeup_timer + function set_wakeup_timer(args) { + // Parse arguments if needed + if (typeof args === 'string') { + try { + args = JSON.parse(args); + } catch (e) { + return "Error: Invalid arguments format"; + } + } + + // Check required arguments + const seconds = args?.seconds; + if (seconds === undefined || seconds < 0) { + return "Error: seconds not specified or invalid"; + } + + const message = args?.message; + if (!message) { + return "Error: message not specified"; + } + + // Create a unique ID for the timer + const timer_id = Date.now().toString() + Math.random().toString(36).substr(2, 5); + + // Calculate expiry time + const expiry_time = new Date(Date.now() + seconds * 1000); + + // Create timer object + const timer = { + id: timer_id, + seconds: seconds, + message: message, + created_time: new Date(), + expiry_time: expiry_time + }; + + // Add to wakeup schedule + wakeup_timers.push(timer); + + // Set the JavaScript timeout + setTimeout(() => { + // Add message to chat + const chatBox = document.getElementById("chatBox"); + const messageDiv = document.createElement("div"); + messageDiv.className = "user-text"; + messageDiv.textContent = "WAKEUP:" + message; + chatBox.appendChild(messageDiv); + chatBox.scrollTop = chatBox.scrollHeight; + + add_text_to_debug("Wakeup timer triggered: " + message); + + // Remove from wakeup schedule + const index = wakeup_timers.findIndex(t => t.id === timer_id); + if (index !== -1) { + wakeup_timers.splice(index, 1); + } + }, seconds * 1000); + + return "Wakeup timer set for " + seconds + " seconds from now with message: " + message; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - \ No newline at end of file +