feat: begin work on rust backend with networktables

This commit is contained in:
Youwen Wu 2024-02-27 22:54:06 -08:00
parent 39f5492d7d
commit 4fc84c7dba
8 changed files with 156 additions and 20 deletions

View file

@ -9,6 +9,7 @@
"version": "0.0.0",
"dependencies": {
"@fontsource/roboto": "^5.0.8",
"@tauri-apps/api": "^1.5.3",
"@threlte/core": "^7.1.0",
"@threlte/extras": "^8.8.0",
"camera-controls": "^2.8.3",
@ -812,6 +813,20 @@
"vite": "^5.0.0"
}
},
"node_modules/@tauri-apps/api": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.5.3.tgz",
"integrity": "sha512-zxnDjHHKjOsrIzZm6nO5Xapb/BxqUq1tc7cGkFXsFkGTsSWgCPH1D8mm0XS9weJY2OaR73I3k3S+b7eSzJDfqA==",
"engines": {
"node": ">= 14.6.0",
"npm": ">= 6.6.0",
"yarn": ">= 1.19.1"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/tauri"
}
},
"node_modules/@tauri-apps/cli": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.5.10.tgz",

View file

@ -29,6 +29,7 @@
},
"dependencies": {
"@fontsource/roboto": "^5.0.8",
"@tauri-apps/api": "^1.5.3",
"@threlte/core": "^7.1.0",
"@threlte/extras": "^8.8.0",
"camera-controls": "^2.8.3",

View file

@ -66,6 +66,7 @@ checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1"
name = "app"
version = "0.1.0"
dependencies = [
"network-tables",
"serde",
"serde_json",
"tauri",
@ -1528,6 +1529,17 @@ dependencies = [
"simd-adler32",
]
[[package]]
name = "mio"
version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09"
dependencies = [
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys 0.48.0",
]
[[package]]
name = "ndk"
version = "0.6.0"
@ -1556,6 +1568,20 @@ dependencies = [
"jni-sys",
]
[[package]]
name = "network-tables"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7d34242b4ee3505f5d9f6eeb8cc409cfa1f18a517825c78e6001fe304c3977b"
dependencies = [
"futures-util",
"parking_lot",
"rand 0.8.5",
"thiserror",
"tokio",
"tracing",
]
[[package]]
name = "new_debug_unreachable"
version = "1.0.4"
@ -2399,6 +2425,16 @@ version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
[[package]]
name = "socket2"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "soup2"
version = "0.2.1"
@ -2895,8 +2931,25 @@ checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931"
dependencies = [
"backtrace",
"bytes",
"libc",
"mio",
"num_cpus",
"parking_lot",
"pin-project-lite",
"socket2",
"tokio-macros",
"windows-sys 0.48.0",
]
[[package]]
name = "tokio-macros"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.50",
]
[[package]]

View file

@ -18,6 +18,7 @@ tauri-build = { version = "1.5.1", features = [] }
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
tauri = { version = "1.6.0", features = [] }
network-tables = "0.1.3"
[features]
# this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled.

View file

@ -1,8 +1,24 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use tauri::Manager;
mod telemetry;
#[derive(Clone, serde::Serialize)]
struct Payload {
message: String,
}
fn main() {
tauri::Builder::default()
.setup(|app| {
// create app handle and send it to our event listeners
let app_handle = app.app_handle();
telemetry::subscribe_topics(&app_handle);
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
.expect("failed to run app")
}

View file

@ -0,0 +1,30 @@
use tauri::{AppHandle, Manager};
pub fn subscribe_topics(app: &AppHandle) {
let app_handle = app.clone();
app_handle.listen_global("subscribe", |event| {
let parsed: Result<serde_json::Value, serde_json::Error> =
serde_json::from_str(event.payload().unwrap());
match parsed {
Ok(value) => {
// handle the successfully parsed value
let topics = value.as_object();
match topics {
Some(topics) => {
for (key, value) in topics {
println!("{}: {}", key, value);
}
}
None => {
println!("No topics requested!");
}
}
}
Err(err) => {
// handle the error
println!("{:?}", err);
}
}
});
}

View file

@ -13,6 +13,7 @@
import { settingsStore } from './lib/stores/settingsStore'
import getSettings from './lib/utils/getSettings'
import { Canvas } from '@threlte/core'
import { emit } from '@tauri-apps/api/event'
let activeApp: App = 'camera'
let topics: TelemetryTopics = {

View file

@ -1,5 +1,5 @@
import { io } from 'socket.io-client'
import { telemetryStore } from '../stores/telemetryStore'
import { emit, listen } from '@tauri-apps/api/event'
/**
* Connects to sockets and subscribes to specified topics to receive telemetry data.
@ -14,7 +14,7 @@ const onUpdate = (data: TelemetryData) => {
// console.log(data)
}
export const initializeTelemetry = (
export const initializeTelemetry = async (
topics: TelemetryTopics,
refreshRate: number
) => {
@ -25,20 +25,39 @@ export const initializeTelemetry = (
)
}
const socket = io('localhost:1280')
socket.on('connect', () => {
console.log('Socket-IO connected!')
socket.emit('subscribe', topics)
console.log(`Subscribing to topics: ${JSON.stringify(topics)}`)
const unlisten = await listen('hello_from_rust', event => {
console.log(event.event)
console.log(event.payload)
})
socket.on('subscribed', () => {
console.log('Successfully subscribed to requested topics!')
socket.emit('request_data', { refresh_rate: refreshRate })
console.log(`Refreshing at ${refreshRate} Hz`)
})
socket.on('telemetry_data', (data: string) => {
onUpdate(JSON.parse(data))
})
emit('subscribe', topics)
}
// export const initializeTelemetry = (
// topics: TelemetryTopics,
// refreshRate: number
// ) => {
// // Make sure refreshRate is valid
// if (!Number.isInteger(refreshRate) || refreshRate < 1) {
// throw new Error(
// 'refreshRate must be an integer greater than or equal to 1.'
// )
// }
// const socket = io('localhost:1280')
// socket.on('connect', () => {
// console.log('Socket-IO connected!')
// socket.emit('subscribe', topics)
// console.log(`Subscribing to topics: ${JSON.stringify(topics)}`)
// })
// socket.on('subscribed', () => {
// console.log('Successfully subscribed to requested topics!')
// socket.emit('request_data', { refresh_rate: refreshRate })
// console.log(`Refreshing at ${refreshRate} Hz`)
// })
// socket.on('telemetry_data', (data: string) => {
// onUpdate(JSON.parse(data))
// })
// }