From 59aff9708b99c2084d77e93933c7969238b6ce8c Mon Sep 17 00:00:00 2001 From: Ansgar Prause Date: Wed, 6 Mar 2024 22:14:51 +0100 Subject: [PATCH 1/3] Start porting communication to WebRTC --- public/controller.html | 115 +++++++++++++++++++++-------------------- public/display.html | 49 +++++++++--------- public/webrtc.js | 110 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 194 insertions(+), 80 deletions(-) create mode 100644 public/webrtc.js diff --git a/public/controller.html b/public/controller.html index 1bf5f2e..591ff43 100644 --- a/public/controller.html +++ b/public/controller.html @@ -1,60 +1,63 @@ - - - Mobile Laser Pointer - Controller - - - - - - - \ No newline at end of file + sensor.addEventListener("error", (error) => { + if (event.error.name === "NotReadableError") { + console.log("Sensor is not available."); + } + }); + sensor.start(); + + + diff --git a/public/display.html b/public/display.html index 40f7f76..7a49646 100644 --- a/public/display.html +++ b/public/display.html @@ -1,30 +1,31 @@ + + Mobile Laser Pointer - Display + - - Mobile Laser Pointer - Display - + + + + - - - - + - - - \ No newline at end of file + // point.setAttributeNS(null, "cx", 50 + factor * deltaYaw); + // point.setAttributeNS(null, "cy", 50 + factor * deltaRoll); + // }); + // }); + + + diff --git a/public/webrtc.js b/public/webrtc.js new file mode 100644 index 0000000..4b0728b --- /dev/null +++ b/public/webrtc.js @@ -0,0 +1,110 @@ +let peerConnection; +let uuid; +let ws; + +const peerConnectionConfig = { + iceServers: [ + { urls: "stun:stun.stunprotocol.org:3478" }, + { urls: "stun:stun.l.google.com:19302" }, + ], +}; + +export const pageReady = () => { + console.log("page ready"); + + uuid = createUUID(); + + const scheme = location.protocol === "https:" ? "wss" : "ws"; + ws = new WebSocket(`${scheme}://${location.host}`); + + return new Promise((resolve) => { + ws.addEventListener("open", () => { + resolve("open"); + console.log("socket open"); + // ws.send(JSON.stringify({ uuid })); + ws.addEventListener("message", async (message) => { + // console.log("got message", message.data); + if (!peerConnection) { + start(false); + } + + const signal = JSON.parse(message.data); + // console.log("signal", signal); + + if (signal.uuid === uuid) { + return; + } + + if (signal.sdp) { + await peerConnection.setRemoteDescription( + new RTCSessionDescription(signal.sdp) + ); + if (signal.sdp.type === "offer") { + const description = await peerConnection.createAnswer(); + createdDescription(description, ws); + // resolve("sdp"); + } + } else if (signal.ice) { + await peerConnection.addIceCandidate(new RTCIceCandidate(signal.ice)); + // resolve("ice"); + } + }); + }); + }); +}; + +export const start = async (isCaller) => { + // console.log("start", isCaller); + peerConnection = new RTCPeerConnection(peerConnectionConfig); + + peerConnection.addEventListener("icecandidate", (event) => { + console.log("icecandidate"); + if (event.candidate != null) { + ws.send(JSON.stringify({ ice: event.candidate, uuid: uuid })); + } + }); + + if (isCaller) { + const dataChannel = peerConnection.createDataChannel("angles"); + + return new Promise(async (resolve) => { + dataChannel.addEventListener("open", () => { + console.log("data channel open"); + dataChannel.send("Hello World!"); + resolve(dataChannel); + }); + + const description = await peerConnection.createOffer(); + console.log("caller with", description); + createdDescription(description, ws); + }); + } else { + peerConnection.addEventListener("datachannel", (event) => { + console.log("data channel event", event); + event.channel.addEventListener("message", (event) => { + console.log("data channel message:", event.data); + }); + }); + } +}; + +const createdDescription = async (description, ws) => { + console.log("created description", description); + await peerConnection.setLocalDescription(description); + ws.send( + JSON.stringify({ + sdp: peerConnection.localDescription, + uuid: uuid, + }) + ); +}; + +function createUUID() { + function s4() { + return Math.floor((1 + Math.random()) * 0x10000) + .toString(16) + .substring(1); + } + + return `${s4() + s4()}-${s4()}-${s4()}-${s4()}-${s4() + s4() + s4()}`; +} From 33b4dc625473b3a6787eed4b44ead4520e1df920 Mon Sep 17 00:00:00 2001 From: Ansgar Prause Date: Wed, 6 Mar 2024 22:21:16 +0100 Subject: [PATCH 2/3] Move point based on received angles --- public/webrtc.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/public/webrtc.js b/public/webrtc.js index 4b0728b..2890ae2 100644 --- a/public/webrtc.js +++ b/public/webrtc.js @@ -83,6 +83,14 @@ export const start = async (isCaller) => { console.log("data channel event", event); event.channel.addEventListener("message", (event) => { console.log("data channel message:", event.data); + + const { deltaYaw, deltaRoll } = JSON.parse(event.data); + + const point = document.getElementById("circle"); + const factor = 50; + + point.setAttributeNS(null, "cx", 50 + factor * deltaYaw); + point.setAttributeNS(null, "cy", 50 + factor * deltaRoll); }); }); } From 45489aa44763b459c756e7ac8af9e08f36797886 Mon Sep 17 00:00:00 2001 From: Ansgar Prause Date: Wed, 6 Mar 2024 23:04:39 +0100 Subject: [PATCH 3/3] Clean up --- public/controller.html | 11 +---------- public/display.html | 14 +++----------- public/webrtc.js | 14 ++------------ 3 files changed, 6 insertions(+), 33 deletions(-) diff --git a/public/controller.html b/public/controller.html index 591ff43..77999a9 100644 --- a/public/controller.html +++ b/public/controller.html @@ -21,18 +21,9 @@ return [yaw, roll]; } - const options = { frequency: 10, referenceFrame: "device" }; + const options = { frequency: 30, referenceFrame: "device" }; const sensor = new AbsoluteOrientationSensor(options); - // const scheme = location.protocol === "https:" ? "wss" : "ws"; - // const ws = new WebSocket(`${scheme}://${location.host}/`); - // await new Promise((res) => { - // ws.addEventListener("open", (event) => { - // res(); - // }); - // }); - - const factor = 50; let firstRead; sensor.addEventListener("reading", (e) => { const [yaw, roll] = toEuler(e.target.quaternion); diff --git a/public/display.html b/public/display.html index 7a49646..792051d 100644 --- a/public/display.html +++ b/public/display.html @@ -10,22 +10,14 @@ diff --git a/public/webrtc.js b/public/webrtc.js index 2890ae2..957f84e 100644 --- a/public/webrtc.js +++ b/public/webrtc.js @@ -19,17 +19,14 @@ export const pageReady = () => { return new Promise((resolve) => { ws.addEventListener("open", () => { - resolve("open"); + resolve(); console.log("socket open"); - // ws.send(JSON.stringify({ uuid })); ws.addEventListener("message", async (message) => { - // console.log("got message", message.data); if (!peerConnection) { start(false); } const signal = JSON.parse(message.data); - // console.log("signal", signal); if (signal.uuid === uuid) { return; @@ -42,11 +39,9 @@ export const pageReady = () => { if (signal.sdp.type === "offer") { const description = await peerConnection.createAnswer(); createdDescription(description, ws); - // resolve("sdp"); } } else if (signal.ice) { await peerConnection.addIceCandidate(new RTCIceCandidate(signal.ice)); - // resolve("ice"); } }); }); @@ -54,7 +49,6 @@ export const pageReady = () => { }; export const start = async (isCaller) => { - // console.log("start", isCaller); peerConnection = new RTCPeerConnection(peerConnectionConfig); peerConnection.addEventListener("icecandidate", (event) => { @@ -70,19 +64,16 @@ export const start = async (isCaller) => { return new Promise(async (resolve) => { dataChannel.addEventListener("open", () => { console.log("data channel open"); - dataChannel.send("Hello World!"); resolve(dataChannel); }); const description = await peerConnection.createOffer(); - console.log("caller with", description); createdDescription(description, ws); }); } else { peerConnection.addEventListener("datachannel", (event) => { - console.log("data channel event", event); event.channel.addEventListener("message", (event) => { - console.log("data channel message:", event.data); + console.log("data channel message", event.data); const { deltaYaw, deltaRoll } = JSON.parse(event.data); @@ -97,7 +88,6 @@ export const start = async (isCaller) => { }; const createdDescription = async (description, ws) => { - console.log("created description", description); await peerConnection.setLocalDescription(description); ws.send( JSON.stringify({