Compare commits
9 Commits
main
...
imu-kickof
| Author | SHA1 | Date |
|---|---|---|
|
|
e0cd593338 | |
|
|
33f8f61a14 | |
|
|
a6a714f92b | |
|
|
bdcf723ae9 | |
|
|
424403e130 | |
|
|
cc725fe357 | |
|
|
e11cc6b0b0 | |
|
|
f204abebe3 | |
|
|
b0c27a160b |
|
|
@ -29,6 +29,11 @@ work in progress; webxr support for xreal devices
|
|||
- [XR Linux Driver](https://github.com/wheaney/XRLinuxDriver)
|
||||
- [OpenVR-xrealAirGlassesHMD](https://github.com/wheaney/OpenVR-xrealAirGlassesHMD)
|
||||
|
||||
### Community Resources
|
||||
- [AR glasses USB protocols: the Good, the Bad and the Ugly](https://voidcomputing.hu/blog/good-bad-ugly) Void Computing AR API Write Up
|
||||
- [AHRS Drift Analysis - Notebook Gist](https://gist.github.com/CGamesPlay/b3ea7740ea8715d19e89f5511491519f)
|
||||
- [AHRS Drift Overview - Youtube](https://www.youtube.com/watch?v=Hvd9qVIusB0)
|
||||
|
||||
### Utilities
|
||||
|
||||
- 🪞 [Unofficial Firmware Archive Mirror](https://air.msmithdev.com/)
|
||||
|
|
|
|||
12
common.js
12
common.js
|
|
@ -128,7 +128,17 @@ export async function connectDevice() {
|
|||
if (glasses) {
|
||||
return glasses;
|
||||
}
|
||||
return await requestDevice();
|
||||
return await requestDevice({
|
||||
filters: [{
|
||||
vendorId: 0x0486, // ? ASUS Computers Inc. ?
|
||||
}, {
|
||||
vendorId: 0x0483, // STMicroelectronics ?
|
||||
}, {
|
||||
vendorId: 0x0482, // Kyocera Corporation ?
|
||||
}, {
|
||||
vendorId: 0x3318, // Gleaming Reality (Wuxi) Technology Co., LTD ?
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
export async function disconnectDevice() {
|
||||
|
|
|
|||
12
index.html
12
index.html
|
|
@ -51,7 +51,17 @@
|
|||
// Request USB device
|
||||
let device;
|
||||
try {
|
||||
device = await navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341 }] });
|
||||
device = await navigator.usb.requestDevice({
|
||||
filters: [{
|
||||
vendorId: 0x0486, // ? ASUS Computers Inc. ?
|
||||
}, {
|
||||
vendorId: 0x0483, // STMicroelectronics ?
|
||||
}, {
|
||||
vendorId: 0x0482, // Kyocera Corporation ?
|
||||
}, {
|
||||
vendorId: 0x3318, // Gleaming Reality (Wuxi) Technology Co., LTD ?
|
||||
}]
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("No device was selected", err);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,9 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="noSupportHid"></div>
|
||||
<div id="listEndpoints">
|
||||
<button onclick="listEndpoints()">list endpoints</button>
|
||||
</div>
|
||||
<div id="connect"><button>connect</button></div>
|
||||
<div id="disconnect" onclick="disconnectDevices()"><button>disconnect</button></div>
|
||||
<div id="startIMU" style="display: none;" onclick="startIMU()"><button>start headtracking</button></div>
|
||||
|
|
@ -320,8 +323,11 @@
|
|||
// });
|
||||
// }
|
||||
|
||||
function connect() {
|
||||
window.connected_devices = [];
|
||||
|
||||
window.connect = function() {
|
||||
Common.connectDevice().then(async glasses => {
|
||||
connected_devices.push(glasses);
|
||||
if (glasses) {
|
||||
document.getElementById('startIMU').style.display = 'block'
|
||||
document.getElementById('hadConnect').style.display = 'block'
|
||||
|
|
@ -337,6 +343,8 @@
|
|||
// document.getElementById('sn').innerHTML = getSN()
|
||||
// document.getElementById('version').innerText = '版本号' + firmwareMcu()
|
||||
setOutput('glasses : ' + glasses.toString());
|
||||
}).catch((err) => {
|
||||
setOutput('glasses : ' + err.toString());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -446,6 +454,11 @@
|
|||
});
|
||||
}
|
||||
|
||||
window.listEndpoints = () => {
|
||||
// Manager.listEndpoints(connected_devices[0]);
|
||||
window.listUsbEndpoints();
|
||||
}
|
||||
|
||||
window.disconnectDevices = () => {
|
||||
window.curGlassesArray.map(g=>{
|
||||
g._device.close();
|
||||
|
|
@ -455,31 +468,44 @@
|
|||
|
||||
window.endpoints = [];
|
||||
|
||||
window.listUsbEndpoints = () => {
|
||||
window.listUsbEndpoints = async () => {
|
||||
window.endpoints = [];
|
||||
// list usb endpoints
|
||||
navigator.usb.requestDevice({filters:[]}).then((device)=>{
|
||||
window.usb_device = device;
|
||||
let device = await navigator.usb.requestDevice({
|
||||
filters: [{
|
||||
vendorId: 0x0486, // ? ASUS Computers Inc. ?
|
||||
}, {
|
||||
vendorId: 0x0483, // STMicroelectronics ?
|
||||
}, {
|
||||
vendorId: 0x0482, // Kyocera Corporation ?
|
||||
}, {
|
||||
vendorId: 0x3318, // Gleaming Reality (Wuxi) Technology Co., LTD ?
|
||||
}]
|
||||
})
|
||||
|
||||
window.usb_device = device;
|
||||
|
||||
//usb_device.configurations[0].interfaces[1].alternates[1].endpoints[0]
|
||||
//usb_device.configurations[0].interfaces[1].alternates[1].endpoints[0]
|
||||
|
||||
for(let configuration of device.configurations){
|
||||
for(let configuration of device.configurations){
|
||||
|
||||
for(let _interface of configuration.interfaces){
|
||||
for(let _interface of configuration.interfaces){
|
||||
|
||||
for(let alternate of _interface?.alternates ?? []){
|
||||
for(let alternate of _interface?.alternates ?? []){
|
||||
|
||||
for(let endpoint of alternate.endpoints){
|
||||
for(let endpoint of alternate.endpoints){
|
||||
|
||||
window.endpoints.push(endpoint);
|
||||
}
|
||||
window.endpoints.push(endpoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.table(window.endpoints);
|
||||
})
|
||||
}
|
||||
|
||||
console.warn('CONNECTED TO DEVICE: ENDPOINTS:')
|
||||
console.table(window.endpoints);
|
||||
|
||||
// new recursive debug printout:
|
||||
await Manager.listEndpoints(device)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -132,9 +132,6 @@ window.logPackets = () => {
|
|||
|
||||
export default class Glasses extends EventTarget {
|
||||
|
||||
/* RepeatingDeviceReportPoll */
|
||||
imu_poller_instance = null;
|
||||
|
||||
constructor(device) {
|
||||
console.log('constructing');
|
||||
super();
|
||||
|
|
@ -143,24 +140,6 @@ export default class Glasses extends EventTarget {
|
|||
this._reports = new Map();
|
||||
this._captures = [];
|
||||
|
||||
// creates it, but doesn't start it...
|
||||
this.imu_poller_instance = new RepeatingDeviceReportPoll({
|
||||
interval: 100,
|
||||
callback: async ()=>{
|
||||
this.sendReportTimeout(Protocol.MESSAGES.R_IMU_DATA, [0x40]).then((report)=>{
|
||||
if(report){
|
||||
console.log('got report',report)
|
||||
}else{
|
||||
console.log('no report')
|
||||
}
|
||||
}).catch((e)=>{
|
||||
console.error('error sending report',e)
|
||||
}).finally(()=>{
|
||||
//console.log('finally')
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// set input listener
|
||||
device.oninputreport = this._handleInputReport.bind(this);
|
||||
|
||||
|
|
@ -364,7 +343,7 @@ export default class Glasses extends EventTarget {
|
|||
return out
|
||||
}).join(' ');
|
||||
|
||||
document.getElementById('imu').innerHTML = stringified
|
||||
//document.getElementById('imu').innerHTML = stringified
|
||||
|
||||
// debugger;
|
||||
if(current < stop_at){
|
||||
|
|
@ -465,7 +444,7 @@ export default class Glasses extends EventTarget {
|
|||
|
||||
}
|
||||
|
||||
class RepeatingDeviceReportPoll {
|
||||
class StartableEndableRepeatingCallback {
|
||||
timer = null;
|
||||
constructor(opts){
|
||||
opts = opts || {};
|
||||
|
|
|
|||
|
|
@ -134,6 +134,39 @@ export async function getFirmwareVersionInDsp() {
|
|||
});
|
||||
}
|
||||
|
||||
export async function listEndpoints(device) {
|
||||
await device.open();
|
||||
|
||||
// Listing available configurations valid for selection
|
||||
let configurations = device.configurations;
|
||||
for (let i = 0; i < configurations.length; i++) {
|
||||
console.log(`Configuration ${i}: ${configurations[i].configurationValue}`);
|
||||
|
||||
try{
|
||||
// Select the current configuration
|
||||
// Assuming the configuration is 0-based
|
||||
await device.selectConfiguration(i+1);
|
||||
|
||||
// Iterate over all available interfaces for the current configuration and claim them
|
||||
for (let j = 0; j < device.configuration.interfaces.length; j++) {
|
||||
try{
|
||||
await device.claimInterface(j);
|
||||
device.configuration.interfaces[j].alternates.forEach((alternate) => {
|
||||
console.log(`Configuration ${i}, iface ${j} Alternate ${alternate.alternateSetting}`);
|
||||
alternate.endpoints.forEach((endpoint) => {
|
||||
console.log(`Endpoint ${endpoint.endpointNumber} Direction ${endpoint.direction}`);
|
||||
});
|
||||
});
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
}catch(e){
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parameters required for the progress bar
|
||||
// function progress(cur, all) {
|
||||
// current = cur
|
||||
|
|
@ -183,8 +216,19 @@ async function waitBootDevice() {
|
|||
}
|
||||
// await requestDevice()
|
||||
|
||||
// await navigator.hid.requestDevice({
|
||||
// filters: [{ vendorId: Protocol.NREAL_VENDOR_ID, productId: Protocol.NREAL_BOOT_PRODUCT_ID }]
|
||||
// });
|
||||
await navigator.hid.requestDevice({
|
||||
filters: [{ vendorId: Protocol.NREAL_VENDOR_ID, productId: Protocol.NREAL_BOOT_PRODUCT_ID }]
|
||||
filters: [{
|
||||
vendorId: 0x0486, // ? ASUS Computers Inc. ?
|
||||
}, {
|
||||
vendorId: 0x0483, // STMicroelectronics ?
|
||||
}, {
|
||||
vendorId: 0x0482, // Kyocera Corporation ?
|
||||
}, {
|
||||
vendorId: 0x3318, // Gleaming Reality (Wuxi) Technology Co., LTD ?
|
||||
}]
|
||||
});
|
||||
const time = new Date().getTime();
|
||||
while ((new Date().getTime() - time) < 2000) {
|
||||
|
|
@ -241,124 +285,124 @@ export function Asc2Hex(value) {
|
|||
// });
|
||||
// }
|
||||
|
||||
export async function upgradeInDsp(data) {
|
||||
let glasses = await common.connectDevice();
|
||||
if (!glasses) {
|
||||
return false;
|
||||
}
|
||||
return sendFirmwareInDsp(glasses, data);
|
||||
}
|
||||
// export async function upgradeInDsp(data) {
|
||||
// let glasses = await common.connectDevice();
|
||||
// if (!glasses) {
|
||||
// return false;
|
||||
// }
|
||||
// return sendFirmwareInDsp(glasses, data);
|
||||
// }
|
||||
|
||||
/** need to upgrade firmware DP version? */
|
||||
export async function isNeedUpgradeInDp() {
|
||||
let glasses = await common.connectDevice();
|
||||
if (!glasses) {
|
||||
return 'not found device';
|
||||
}
|
||||
return glasses.sendReportTimeout(Protocol.MESSAGES.R_DP7911_FW_IS_UPDATE)
|
||||
.then(report => {
|
||||
if (reportSuccess(report)) {
|
||||
return report.payload[0]
|
||||
}
|
||||
});
|
||||
}
|
||||
// export async function isNeedUpgradeInDp() {
|
||||
// let glasses = await common.connectDevice();
|
||||
// if (!glasses) {
|
||||
// return 'not found device';
|
||||
// }
|
||||
// return glasses.sendReportTimeout(Protocol.MESSAGES.R_DP7911_FW_IS_UPDATE)
|
||||
// .then(report => {
|
||||
// if (reportSuccess(report)) {
|
||||
// return report.payload[0]
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
export async function upgradeInDp() {
|
||||
let glasses = await common.connectDevice();
|
||||
if (!glasses) {
|
||||
return false;
|
||||
}
|
||||
// 添加眼镜休眠时间
|
||||
const time = Protocol.time2Bytes('600');
|
||||
return glasses.sendReportTimeout(Protocol.MESSAGES.W_SLEEP_TIME, time)
|
||||
.then(report => {
|
||||
if (reportSuccess(report)) {
|
||||
return glasses.sendReportTimeout(Protocol.MESSAGES.W_UPDATE_DP)
|
||||
.then(async report => {
|
||||
if (reportSuccess(report)) {
|
||||
// wait for air dp upgrade completed
|
||||
while(!glasses._reports.has(27661) && common.curGlasses){
|
||||
await sleep(500)
|
||||
dpCurrent = glasses._reports.get(27660) ? glasses._reports.get(27660).status : 0
|
||||
progressInDp(dpCurrent)
|
||||
}
|
||||
// export async function upgradeInDp() {
|
||||
// let glasses = await common.connectDevice();
|
||||
// if (!glasses) {
|
||||
// return false;
|
||||
// }
|
||||
// // 添加眼镜休眠时间
|
||||
// const time = Protocol.time2Bytes('600');
|
||||
// return glasses.sendReportTimeout(Protocol.MESSAGES.W_SLEEP_TIME, time)
|
||||
// .then(report => {
|
||||
// if (reportSuccess(report)) {
|
||||
// return glasses.sendReportTimeout(Protocol.MESSAGES.W_UPDATE_DP)
|
||||
// .then(async report => {
|
||||
// if (reportSuccess(report)) {
|
||||
// // wait for air dp upgrade completed
|
||||
// while(!glasses._reports.has(27661) && common.curGlasses){
|
||||
// await sleep(500)
|
||||
// dpCurrent = glasses._reports.get(27660) ? glasses._reports.get(27660).status : 0
|
||||
// progressInDp(dpCurrent)
|
||||
// }
|
||||
|
||||
return glasses._reports.get(27661) ? glasses._reports.get(27661).status == 0 : false
|
||||
}
|
||||
// return glasses._reports.get(27661) ? glasses._reports.get(27661).status == 0 : false
|
||||
// }
|
||||
|
||||
return false
|
||||
});
|
||||
}
|
||||
});
|
||||
// return false
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
|
||||
async function sendFirmwareInMcu(bootDevice, data) {
|
||||
// async function sendFirmwareInMcu(bootDevice, data) {
|
||||
|
||||
let ofs = 0;
|
||||
const firstPackLen = 24;
|
||||
const fwLen = data.byteLength;
|
||||
// let ofs = 0;
|
||||
// const firstPackLen = 24;
|
||||
// const fwLen = data.byteLength;
|
||||
|
||||
|
||||
|
||||
|
||||
let report = await bootDevice.sendReportTimeout(
|
||||
Protocol.MESSAGES.W_UPDATE_MCU_APP_FW_START,
|
||||
data.slice(ofs, ofs + firstPackLen));
|
||||
if (!reportSuccess(report)) {
|
||||
console.error('send fw data failed');
|
||||
return false;
|
||||
}
|
||||
ofs += firstPackLen;
|
||||
// let report = await bootDevice.sendReportTimeout(
|
||||
// Protocol.MESSAGES.W_UPDATE_MCU_APP_FW_START,
|
||||
// data.slice(ofs, ofs + firstPackLen));
|
||||
// if (!reportSuccess(report)) {
|
||||
// console.error('send fw data failed');
|
||||
// return false;
|
||||
// }
|
||||
// ofs += firstPackLen;
|
||||
|
||||
while (ofs < fwLen) {
|
||||
progress(ofs, fwLen)
|
||||
if ((ofs + 42) > fwLen) {
|
||||
report = await bootDevice.sendReportTimeout(
|
||||
Protocol.MESSAGES.W_UPDATE_MCU_APP_FW_TRANSMIT,
|
||||
data.slice(ofs, fwLen));
|
||||
if (!reportSuccess(report)) {
|
||||
console.error('send fw data failed');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
report = await bootDevice.sendReportTimeout(
|
||||
Protocol.MESSAGES.W_UPDATE_MCU_APP_FW_TRANSMIT,
|
||||
data.slice(ofs, ofs + 42));
|
||||
// while (ofs < fwLen) {
|
||||
// progress(ofs, fwLen)
|
||||
// if ((ofs + 42) > fwLen) {
|
||||
// report = await bootDevice.sendReportTimeout(
|
||||
// Protocol.MESSAGES.W_UPDATE_MCU_APP_FW_TRANSMIT,
|
||||
// data.slice(ofs, fwLen));
|
||||
// if (!reportSuccess(report)) {
|
||||
// console.error('send fw data failed');
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// report = await bootDevice.sendReportTimeout(
|
||||
// Protocol.MESSAGES.W_UPDATE_MCU_APP_FW_TRANSMIT,
|
||||
// data.slice(ofs, ofs + 42));
|
||||
|
||||
if (!reportSuccess(report)) {
|
||||
console.error('send fw data failed');
|
||||
return false;
|
||||
}
|
||||
ofs += 42;
|
||||
}
|
||||
// if (!reportSuccess(report)) {
|
||||
// console.error('send fw data failed');
|
||||
// return false;
|
||||
// }
|
||||
// ofs += 42;
|
||||
// }
|
||||
|
||||
/* send finish */
|
||||
report = await bootDevice.sendReportTimeout(Protocol.MESSAGES.W_UPDATE_MCU_APP_FW_FINISH);
|
||||
// if (!reportSuccess(report)) {
|
||||
// console.error('send fw data failed');
|
||||
// return false;
|
||||
// }
|
||||
/* jump to app */
|
||||
report = await bootDevice.sendReportTimeout(Protocol.MESSAGES.W_BOOT_JUMP_TO_APP);
|
||||
// if (!reportSuccess(report)) {
|
||||
// console.error('send fw data failed');
|
||||
// return false;
|
||||
// }
|
||||
// /* send finish */
|
||||
// report = await bootDevice.sendReportTimeout(Protocol.MESSAGES.W_UPDATE_MCU_APP_FW_FINISH);
|
||||
// // if (!reportSuccess(report)) {
|
||||
// // console.error('send fw data failed');
|
||||
// // return false;
|
||||
// // }
|
||||
// /* jump to app */
|
||||
// report = await bootDevice.sendReportTimeout(Protocol.MESSAGES.W_BOOT_JUMP_TO_APP);
|
||||
// // if (!reportSuccess(report)) {
|
||||
// // console.error('send fw data failed');
|
||||
// // return false;
|
||||
// // }
|
||||
|
||||
// Send the command to upgrade the DP
|
||||
// report = await bootDevice.sendReportTimeout(Protocol.MESSAGES.W_UPDATE_DP);
|
||||
// // Send the command to upgrade the DP
|
||||
// // report = await bootDevice.sendReportTimeout(Protocol.MESSAGES.W_UPDATE_DP);
|
||||
|
||||
|
||||
current = 0
|
||||
total = 0
|
||||
return true;
|
||||
// current = 0
|
||||
// total = 0
|
||||
// return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
// }
|
||||
|
||||
/*
|
||||
async function sendFirmwareInDsp(glasses, data) {
|
||||
|
||||
let ofs = 0;
|
||||
|
|
@ -441,7 +485,7 @@ async function sendFirmwareInDsp(glasses, data) {
|
|||
}
|
||||
}
|
||||
|
||||
/* send finish */
|
||||
/* send finish *-/
|
||||
report = await glasses.sendReportTimeout(Protocol.MESSAGES.W_UPDATE_DSP_APP_FW_FINISH);
|
||||
// if (!reportSuccess(report)) {
|
||||
// console.error('send fw data failed');
|
||||
|
|
@ -449,7 +493,7 @@ async function sendFirmwareInDsp(glasses, data) {
|
|||
// }
|
||||
// dsp write bin ==> first 100%
|
||||
progress(ofs,fwLen)
|
||||
/* Check whether the upgrade is complete */
|
||||
/* Check whether the upgrade is complete *-/
|
||||
// air DSP judge for flash&boot
|
||||
// 删除之前刷新boot的过程,dsp重新刷新
|
||||
glasses._reports.delete(27664)
|
||||
|
|
@ -487,6 +531,9 @@ async function sendFirmwareInDsp(glasses, data) {
|
|||
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// Delay synchronization program execution
|
||||
function sleep(delay) {
|
||||
|
|
@ -514,10 +561,7 @@ export async function startIMU() {
|
|||
return Promise.reject('no device connected')
|
||||
}
|
||||
|
||||
// kick off polling
|
||||
glasses.startIMUPolling();
|
||||
|
||||
return glasses.sendReportTimeout(Protocol.MESSAGES.W_TOGGLE_IMU, [0x1])
|
||||
return glasses.sendReportTimeout(0x00, Protocol.MAGIC_PAYLOAD)
|
||||
.then(report => {
|
||||
console.warn('startIMU -> report',report);
|
||||
if (reportSuccess(report)){
|
||||
|
|
@ -544,6 +588,32 @@ export async function stopIMU() {
|
|||
})
|
||||
}
|
||||
|
||||
export async function getDisplayMode(){
|
||||
let glasses = await common.connectDevice();
|
||||
if (!glasses) {
|
||||
return 'not found device';
|
||||
}
|
||||
return glasses.sendReportTimeout(Protocol.MESSAGES.R_DISPLAY_MODE)
|
||||
.then(report => {
|
||||
if (reportSuccess(report)) {
|
||||
return report.payload[0];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function setDisplayMode(mode){
|
||||
let glasses = await common.connectDevice();
|
||||
if (!glasses) {
|
||||
return 'not found device';
|
||||
}
|
||||
return glasses.sendReportTimeout(Protocol.MESSAGES.W_DISPLAY_MODE, [mode])
|
||||
.then(report => {
|
||||
if (reportSuccess(report)) {
|
||||
return report.payload[0];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** read air glassess Brightness */
|
||||
export async function getBrightness() {
|
||||
let glasses = await common.connectDevice();
|
||||
|
|
@ -551,7 +621,7 @@ export async function getBrightness() {
|
|||
return 'not found device';
|
||||
}
|
||||
// what's the chance the getBrightness is the same as setBrightness?
|
||||
return glasses.sendReportTimeout(Protocol.MESSAGES.W_BRIGHTNESS)
|
||||
return glasses.sendReportTimeout(Protocol.MESSAGES.R_BRIGHTNESS)
|
||||
.then(report => {
|
||||
if (reportSuccess(report)) {
|
||||
return report.payload;
|
||||
|
|
|
|||
|
|
@ -7,79 +7,61 @@ const CRC_OFS = 1;
|
|||
const TS_OFS = 7;
|
||||
const RESERVED_OFS = 17;
|
||||
|
||||
// send to device 3 to enable IMU tracking reporting (removed first byte 0x00)
|
||||
export const MAGIC_PAYLOAD = new Uint8Array([0xaa, 0xc5, 0xd1, 0x21, 0x42, 0x04, 0x00, 0x19, 0x01]);
|
||||
|
||||
export const NREAL_VENDOR_ID = 0x3318;
|
||||
export const BOOT_PRODUCT_ID = 0x0423;
|
||||
export const IMU_TIMEOUT = 250;
|
||||
class CliDisplayMode {
|
||||
static SameOnBoth = "2d";
|
||||
static Stereo = "3d";
|
||||
static HalfSBS = "halfsbs";
|
||||
static HighRefreshRate = "high-refresh-rate-2d";
|
||||
static HighRefreshRateSBS = "high-refresh-rate-3d";
|
||||
|
||||
export const ERRORS = {
|
||||
DEVICE3_ERROR_NO_ERROR: 0,
|
||||
DEVICE3_ERROR_NO_DEVICE: 1,
|
||||
DEVICE3_ERROR_NO_HANDLE: 2,
|
||||
DEVICE3_ERROR_NO_ALLOCATION: 3,
|
||||
DEVICE3_ERROR_WRONG_SIZE: 4,
|
||||
DEVICE3_ERROR_FILE_NOT_OPEN: 5,
|
||||
DEVICE3_ERROR_FILE_NOT_CLOSED: 6,
|
||||
DEVICE3_ERROR_LOADING_FAILED: 7,
|
||||
DEVICE3_ERROR_SAVING_FAILED: 8,
|
||||
DEVICE3_ERROR_UNPLUGGED: 9,
|
||||
DEVICE3_ERROR_UNEXPECTED: 10,
|
||||
DEVICE3_ERROR_WRONG_SIGNATURE: 11,
|
||||
DEVICE3_ERROR_INVALID_VALUE: 12,
|
||||
DEVICE3_ERROR_NOT_INITIALIZED: 13,
|
||||
DEVICE3_ERROR_PAYLOAD_FAILED: 14,
|
||||
DEVICE3_ERROR_UNKNOWN: 15,
|
||||
}
|
||||
|
||||
class Device3Packet {
|
||||
/*
|
||||
uint8_t signature [2];
|
||||
uint8_t temperature [2];
|
||||
uint64_t timestamp;
|
||||
uint8_t angular_multiplier [2];
|
||||
uint8_t angular_divisor [4];
|
||||
uint8_t angular_velocity_x [3];
|
||||
uint8_t angular_velocity_y [3];
|
||||
uint8_t angular_velocity_z [3];
|
||||
uint8_t acceleration_multiplier [2];
|
||||
uint8_t acceleration_divisor [4];
|
||||
uint8_t acceleration_x [3];
|
||||
uint8_t acceleration_y [3];
|
||||
uint8_t acceleration_z [3];
|
||||
uint8_t magnetic_multiplier [2];
|
||||
uint8_t magnetic_divisor [4];
|
||||
uint8_t magnetic_x [2];
|
||||
uint8_t magnetic_y [2];
|
||||
uint8_t magnetic_z [2];
|
||||
uint32_t checksum;
|
||||
uint8_t _padding [6];
|
||||
*/
|
||||
constructor() {
|
||||
this.signature = new Uint8Array(2);
|
||||
this.temperature = new Uint8Array(2);
|
||||
this.timestamp = new Uint8Array(8);
|
||||
this.angular_multiplier = new Uint8Array(2);
|
||||
this.angular_divisor = new Uint8Array(4);
|
||||
this.angular_velocity_x = new Uint8Array(3);
|
||||
this.angular_velocity_y = new Uint8Array(3);
|
||||
this.angular_velocity_z = new Uint8Array(3);
|
||||
this.acceleration_multiplier = new Uint8Array(2);
|
||||
this.acceleration_divisor = new Uint8Array(4);
|
||||
this.acceleration_x = new Uint8Array(3);
|
||||
this.acceleration_y = new Uint8Array(3);
|
||||
this.acceleration_z = new Uint8Array(3);
|
||||
this.magnetic_multiplier = new Uint8Array(2);
|
||||
this.magnetic_divisor = new Uint8Array(4);
|
||||
this.magnetic_x = new Uint8Array(2);
|
||||
this.magnetic_y = new Uint8Array(2);
|
||||
this.magnetic_z = new Uint8Array(2);
|
||||
this.checksum = new Uint8Array(4);
|
||||
this._padding = new Uint8Array(6);
|
||||
static getDisplayModeByte(displayMode) {
|
||||
switch (displayMode) {
|
||||
case CliDisplayMode.SameOnBoth:
|
||||
return 1;
|
||||
case CliDisplayMode.Stereo:
|
||||
return 3;
|
||||
case CliDisplayMode.HalfSBS:
|
||||
return 8;
|
||||
case CliDisplayMode.HighRefreshRate:
|
||||
return 11;
|
||||
case CliDisplayMode.HighRefreshRateSBS:
|
||||
return 9;
|
||||
default:
|
||||
throw new Error("Invalid display mode");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Example usage
|
||||
let displayMode = CliDisplayMode.Stereo; // This can be dynamically set
|
||||
let displayModeByte = CliDisplayMode.getDisplayModeByte(displayMode);
|
||||
console.log(displayModeByte);
|
||||
|
||||
|
||||
export const NREAL_VENDOR_ID = 0x3318;
|
||||
export const BOOT_PRODUCT_ID = 0x0423;
|
||||
//export const IMU_RATE = 1000; // 1KHz
|
||||
|
||||
// based on 24bit signed int w/ FSR = +/-2000 dps, datasheet option
|
||||
export const GYRO_SCALAR = (1.0 / 8388608.0 * 2000.0)
|
||||
|
||||
// based on 24bit signed int w/ FSR = +/-16 g, datasheet option
|
||||
export const ACCEL_SCALAR = (1.0 / 8388608.0 * 16.0)
|
||||
|
||||
// ticks are in nanoseconds, 1000 Hz packets
|
||||
// #define TICK_LEN (1.0f / 1E9f)
|
||||
|
||||
class AirSample {
|
||||
tick;
|
||||
ang_vel; // 3
|
||||
accel; // 3
|
||||
}
|
||||
|
||||
export const MESSAGES = {
|
||||
|
||||
|
||||
R_MCU_APP_FW_VERSION: 0x26,//MCU APP FW version.
|
||||
R_GLASSID: 0x15,//MCU APP FW version.
|
||||
// R_DSP_APP_FW_VERSION: 0x21,//DSP APP FW version.
|
||||
|
|
@ -88,10 +70,16 @@ export const MESSAGES = {
|
|||
W_ACTIVATION_TIME: 0x2A,//Write activation time
|
||||
W_SLEEP_TIME: 0x1E,//Write unsleep time
|
||||
|
||||
R_IMU_DATA: 0x80,//IMU data
|
||||
UNKNOWN_40: 0x40,//Unknown
|
||||
// R_IMU_DATA: 0x80,//IMU data
|
||||
// UNKNOWN_40: 0x40,//Unknown
|
||||
|
||||
W_TOGGLE_IMU: 0x19,
|
||||
R_DISPLAY_MODE: 0x7,//Read display mode
|
||||
W_DISPLAY_MODE: 0x08,//Write display mode
|
||||
|
||||
R_BRIGHTNESS: 0x0,//Read brightness
|
||||
W_BRIGHTNESS: 0x0,//Write brightness
|
||||
|
||||
W_TOGGLE_IMU: 0x19,
|
||||
W_CANCEL_ACTIVATION: 0x19,
|
||||
|
||||
// R_IS_NEED_UPGRADE_DSP_FW: 0x49,//Check whether the DSP needs to be upgraded.
|
||||
|
|
@ -111,7 +99,7 @@ export const MESSAGES = {
|
|||
W_UPDATE_MCU_APP_FW_FINISH: 0x41, //(Implemented in Boot)
|
||||
W_BOOT_JUMP_TO_APP: 0x42, //(Implemented in Boot)
|
||||
W_MCU_APP_JUMP_TO_BOOT: 0x44,
|
||||
R_DP7911_FW_IS_UPDATE:0x3C,
|
||||
R_DP7911_FW_IS_UPDATE: 0x3C,
|
||||
W_UPDATE_DP: 0x3D,
|
||||
|
||||
|
||||
|
|
@ -133,7 +121,7 @@ export const MESSAGES = {
|
|||
P_UKNOWN_HEARTBEAT_2: 0x6c12
|
||||
};
|
||||
|
||||
export function keyForHex(hex){
|
||||
export function keyForHex(hex) {
|
||||
for (let key in MESSAGES) {
|
||||
if (MESSAGES[key] == hex) {
|
||||
return key;
|
||||
|
|
@ -143,15 +131,15 @@ export function keyForHex(hex){
|
|||
}
|
||||
|
||||
|
||||
export function listKnownCommands(){
|
||||
export function listKnownCommands() {
|
||||
let data = [];
|
||||
Object.keys(MESSAGES).map((key)=>{
|
||||
|
||||
Object.keys(MESSAGES).map((key) => {
|
||||
|
||||
|
||||
data.push({
|
||||
key,
|
||||
hex:'0x'+MESSAGES[key].toString(16),
|
||||
dec:MESSAGES[key]
|
||||
hex: '0x' + MESSAGES[key].toString(16),
|
||||
dec: MESSAGES[key]
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -278,7 +266,7 @@ function get_status_byte(response) {
|
|||
window.unparsed = [];
|
||||
|
||||
// 4-bytes to 32-bit float
|
||||
function four_bytes_to_float(byte_array){
|
||||
function four_bytes_to_float(byte_array) {
|
||||
var data = byte_array; // [64, 226, 157, 10];
|
||||
|
||||
// Create a buffer
|
||||
|
|
@ -306,11 +294,11 @@ export function parse_rsp(rsp) {
|
|||
payload: new Uint8Array()
|
||||
};
|
||||
|
||||
if(rsp[0] !== HEAD){
|
||||
if (rsp[0] !== HEAD) {
|
||||
// console.warn('HEAD mismatch', rsp[0]);
|
||||
// console.warn([...rsp].map(x => x.toString(16).padStart(2,'0')).join(' '));
|
||||
if(window.unparsed.length<1000){
|
||||
window.unparsed.push([...rsp].map(x => x.toString(16).padStart(2,'0')).join(','))
|
||||
if (window.unparsed.length < 1000) {
|
||||
window.unparsed.push([...rsp].map(x => x.toString(16).padStart(2, '0')).join(','))
|
||||
|
||||
// extract 16 32-bit,4-byte floats from 64 bytes
|
||||
// NOPE
|
||||
|
|
@ -408,9 +396,9 @@ export function brightBytes2Int(bright_byte_arr) {
|
|||
export function bytes2Time(bytes) {
|
||||
let time = '';
|
||||
for (let i = bytes.byteLength - 1; i >= 0; i--) {
|
||||
if(i > 3){
|
||||
if (i > 3) {
|
||||
time += bytes[i].toString(2)
|
||||
}else{
|
||||
} else {
|
||||
time += bytes[i].toString(2)
|
||||
// time += bytes[i] << (i * 8);
|
||||
}
|
||||
|
|
@ -418,18 +406,18 @@ export function bytes2Time(bytes) {
|
|||
return time;
|
||||
};
|
||||
|
||||
export function hex2Decimal(byte){
|
||||
export function hex2Decimal(byte) {
|
||||
return parseInt(byte, 16);
|
||||
}
|
||||
|
||||
export function time2Bytes(timeStamp){
|
||||
export function time2Bytes(timeStamp) {
|
||||
let arr = new Uint8Array(8)
|
||||
let len = Math.floor((Number(timeStamp).toString(2).length) / 8)
|
||||
let longN = parseInt(Number(timeStamp).toString(2).substring(0,Number(timeStamp).toString(2).length - 32), 2)
|
||||
let longN = parseInt(Number(timeStamp).toString(2).substring(0, Number(timeStamp).toString(2).length - 32), 2)
|
||||
for (let i = len; i >= 0; i--) {
|
||||
if(i > 3){
|
||||
if (i > 3) {
|
||||
arr[i] = ((longN >>> ((i - 4) * 8)) & 0xFF);
|
||||
}else{
|
||||
} else {
|
||||
arr[i] = ((timeStamp >>> (i * 8)) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue