Skip to content

Commit

Permalink
add ClientMessageManager.set_server_keyframe_id and RemoteGuiInput.po…
Browse files Browse the repository at this point in the history
…p_recent_server_keyframe_id to help the server measure client latency (#1796)
  • Loading branch information
eundersander authored Feb 10, 2024
1 parent 2a5dbae commit cf94ffb
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 12 deletions.
18 changes: 6 additions & 12 deletions habitat-hitl/habitat_hitl/_internal/networking/keyframe_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,12 @@ def ensure_dict(keyframe, key):

if "message" in inc_keyframe:
inc_message = inc_keyframe["message"]
# add/update these messages
for message_key in [
"teleportAvatarBasePosition",
"sceneChanged",
"navmeshVertices",
"isAppReady",
]:
if message_key in inc_message:
ensure_dict(consolidated_keyframe, "message")
consolidated_keyframe["message"][message_key] = inc_message[
message_key
]
# add/update all messages
for message_key in inc_message:
ensure_dict(consolidated_keyframe, "message")
consolidated_keyframe["message"][message_key] = inc_message[
message_key
]

# todo: lights, userTransforms

Expand Down
3 changes: 3 additions & 0 deletions habitat-hitl/habitat_hitl/core/client_message_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ def signal_app_ready(self):
"""
self._message["isAppReady"] = True

def set_server_keyframe_id(self, keyframe_id):
self._message["serverKeyframeId"] = keyframe_id

def update_navmesh_triangles(self, triangle_vertices):
r"""
Send a navmesh. triangle_vertices should be a list of vertices, 3 per triangle.
Expand Down
18 changes: 18 additions & 0 deletions habitat-hitl/habitat_hitl/core/remote_gui_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from habitat_hitl.core.gui_input import GuiInput


# todo: rename to RemoteClientState
class RemoteGuiInput:
def __init__(self, interprocess_record, debug_line_render):
self._recent_client_states = []
Expand Down Expand Up @@ -44,6 +45,23 @@ def get_history_timestep(self):
def get_connection_params(self):
return self._connection_params

def pop_recent_server_keyframe_id(self):
"""
Removes and returns ("pops") the recentServerKeyframeId included in the latest client state.
The removal behavior here is to help user code by only returning a keyframe ID when a new (unseen) one is available.
"""
if len(self._recent_client_states) == 0:
return None

latest_client_state = self._recent_client_states[0]
if "recentServerKeyframeId" not in latest_client_state:
return None

retval = int(latest_client_state["recentServerKeyframeId"])
del latest_client_state["recentServerKeyframeId"]
return retval

def get_head_pose(self, history_index=0):
if history_index >= len(self._recent_client_states):
return None, None
Expand Down
38 changes: 38 additions & 0 deletions habitat-hitl/habitat_hitl/scripts/stub_client.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
var url = 'ws://' + ip + ':' + port;
document.getElementById('serverUrl').textContent = 'Server URL: ' + url;
ws = new WebSocket(url);
var sendIntervalId = null; // Variable to hold the ID of the interval
var recentServerKeyframeId = null;

ws.onopen = function() {
document.getElementById('status').textContent = 'Connected';
Expand All @@ -48,6 +50,18 @@
document.getElementById('serverPort').disabled = true;
document.getElementById('sendButton').disabled = false;
ws.send('client ready!'); // Send "client ready!" to the server

// Start sending messages at 10 Hz
sendIntervalId = setInterval(function() {
var dict = {}; // Create an empty JavaScript object

// Our stub client only sends recentServerKeyframeId. It doesn't send local GUI input or other client state.
if (recentServerKeyframeId != null) {
dict["recentServerKeyframeId"] = recentServerKeyframeId;
}
var message = JSON.stringify(dict); // Convert the object to a JSON string
ws.send(message); // Send the JSON string
}, 100); // Repeat every 100 milliseconds
};

ws.onclose = function() {
Expand All @@ -57,10 +71,34 @@
document.getElementById('serverIp').disabled = false;
document.getElementById('serverPort').disabled = false;
document.getElementById('sendButton').disabled = true;

if (sendIntervalId) {
clearInterval(sendIntervalId);
sendIntervalId = null;
}
recentServerKeyframeId = null;

};

ws.onmessage = function() {
messageCount++;

var message = event.data;
var dict = JSON.parse(message);

// parse the latest serverKeyframeId from received keyframes
if ("keyframes" in dict) {
keyframes = dict["keyframes"]
if (keyframes.length) {
keyframe = keyframes[keyframes.length - 1];
if ("message" in keyframe) {
message = keyframe["message"]
if ("serverKeyframeId" in message) {
recentServerKeyframeId = message["serverKeyframeId"];
}
}
}
}
};
}

Expand Down

0 comments on commit cf94ffb

Please sign in to comment.