@ioai/robot_viewer 1.1.1 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -0
- package/bin/cli.js +75 -4
- package/dist/assets/js/PlotPanel-b7b606e3.js +1 -0
- package/dist/assets/js/index-90ddef80.js +6 -0
- package/dist/assets/js/{mujoco_wasm-e013cb22.js → mujoco_wasm-d0cfe29a.js} +1 -1
- package/dist/camera-publish-worker.js +1 -1
- package/dist/heartbeat-worker.js +1 -1
- package/dist/index.html +2 -2
- package/package.json +5 -5
- package/server/static-server.js +39 -7
- package/dist/assets/js/PlotPanel-64b4820e.js +0 -1
- package/dist/assets/js/index-2e5294e6.js +0 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
const PREVIEW_MIME='image/jpeg';const PREVIEW_QUALITY=0.7;const MAX_SOCKET_BUFFER=0x4*0x400*0x400;const MAX_QUEUE=0x3;const DOMAIN_ID_TOPIC='/robot_viewer/domain_id';const DOMAIN_ID_TYPE='std_msgs/msg/Int32';const DOMAIN_ID_TIMEOUT_MS=0x1388;const TOPIC_TYPE='sensor_msgs/msg/CompressedImage';const ENCODINGS=[{'format':'jpeg','mime':'image/jpeg','lossy':!![]},{'format':'png','mime':'image/png','lossy':![]},{'format':'webp','mime':'image/webp','lossy':!![]}];const MIME_TO_FORMAT={'image/jpeg':'jpeg','image/png':'png','image/webp':'webp'};const requestedEncoding=()=>ENCODINGS['find'](_0x3dff2d=>_0x3dff2d['format']===cfg['format'])||ENCODINGS[0x0];const formatOfBlob=(_0x5ec4d2,_0x1ff46e)=>MIME_TO_FORMAT[_0x5ec4d2]||_0x1ff46e;let encodingSupport=null;async function probeEncodings(){if(!encodingSupport){const _0x55e441=[];try{const _0x2fa405=new OffscreenCanvas(0x8,0x8);const _0x333b09=_0x2fa405['getContext']('2d');_0x333b09['putImageData'](new ImageData(new Uint8ClampedArray(0x8*0x8*0x4),0x8,0x8),0x0,0x0);for(const _0x358006 of ENCODINGS){let _0x5f5c6b=![];try{const _0x36f746=await _0x2fa405['convertToBlob'](_0x358006['lossy']?{'type':_0x358006['mime'],'quality':0.8}:{'type':_0x358006['mime']});_0x5f5c6b=!!_0x36f746&&_0x36f746['type']===_0x358006['mime'];}catch(_0x573601){_0x5f5c6b=![];}_0x55e441['push']({'format':_0x358006['format'],'supported':_0x5f5c6b});}}catch(_0x56704f){for(const _0x4b0027 of ENCODINGS)_0x55e441['push']({'format':_0x4b0027['format'],'supported':_0x4b0027['format']==='jpeg'});}encodingSupport=_0x55e441;}self['postMessage']({'cmd':'encodings','list':encodingSupport});return encodingSupport;}function bytesToBase64(_0x1e9bda){const _0x15d925=0x8000;let _0x1f2fe0='';for(let _0x28167c=0x0;_0x28167c<_0x1e9bda['length'];_0x28167c+=_0x15d925){_0x1f2fe0+=String['fromCharCode']['apply'](null,_0x1e9bda['subarray'](_0x28167c,_0x28167c+_0x15d925));}return btoa(_0x1f2fe0);}let cfg={'url':'','topic':'','type':TOPIC_TYPE,'frameId':'','rate':0xa,'format':'jpeg','quality':0x50,'preview':![],'previewWidth':0x140};let ws=null;let connected=![];let running=![];let connectionWanted=![];let reconnectTimer=null;let retryDelay=0x7d0;let connectStartedAt=-0x1;let advertisedTopic=null;let gridTimer=null;let queue=[];let pendingNeed=0x0;let encodeInFlight=0x0;let lastNeedAt=0x0;let lastEncodeAt=0x0;let domainId=undefined;let domainIdTimer=null;let domainIdSubscribed=![];let canvas=null;let ctx=null;let previewCanvas=null;let previewCtx=null;let statsTimer=null;const NEED_TIMEOUT_MS=0x5dc;const ENCODE_TIMEOUT_MS=0x1388;const CONNECT_TIMEOUT_MS=0x1388;const stats={'published':0x0,'dropped':0x0,'underruns':0x0,'stalled':0x0,'reconnects':0x0,'payloadBytes':0x0,'encodeMs':0x0,'captureMs':0x0,'rate':0x0,'lastDrop':null};let rateWindow={'start':0x0,'count':0x0};let produceSamples=[];const clampedRate=()=>Math['max'](0x1,Math['min'](0x78,Math['round'](cfg['rate'])||0xa));const ROUND_TRIP_MS=0x3;const MIN_DEPTH=0x2;const targetDepth=()=>{const _0x3cfccc=0x3e8/clampedRate();const _0x1d88b1=produceSamples['length']?Math['max'](...produceSamples):0x0;if(_0x1d88b1<=0x0)return MIN_DEPTH;const _0x6efe43=Math['ceil']((_0x1d88b1+ROUND_TRIP_MS)*1.15/_0x3cfccc);return Math['min'](MAX_QUEUE,Math['max'](MIN_DEPTH,_0x6efe43));};function closeSocket(){stopDomainIdQuery();if(ws){const _0x4ef6f5=ws;_0x4ef6f5['onopen']=null;_0x4ef6f5['onclose']=null;_0x4ef6f5['onerror']=null;try{_0x4ef6f5['close']();}catch(_0x46c81f){}ws=null;}connected=![];advertisedTopic=null;}function scheduleReconnect(){if(!connectionWanted||reconnectTimer)return;reconnectTimer=setTimeout(()=>{reconnectTimer=null;if(running)connect(cfg['url']);},retryDelay);retryDelay=Math['min'](0x2710,retryDelay*0x2);}function connect(_0x11488b){if(ws&&connected&&ws['readyState']===0x1&&cfg['url']===_0x11488b){self['postMessage']({'cmd':'state','connected':!![],'reused':!![]});return;}closeSocket();if(!_0x11488b){self['postMessage']({'cmd':'state','connected':![],'error':'缺少\x20rosbridge\x20地址'});return;}connectStartedAt=performance['now']();try{ws=new WebSocket(_0x11488b);}catch(_0x13f154){self['postMessage']({'cmd':'state','connected':![],'error':String(_0x13f154&&_0x13f154['message']||_0x13f154)});scheduleReconnect();return;}ws['onopen']=()=>{connected=!![];connectStartedAt=-0x1;retryDelay=0x7d0;advertise();queryDomainId();if(running)startGrid();self['postMessage']({'cmd':'state','connected':!![]});};ws['onclose']=()=>{connected=![];connectStartedAt=-0x1;advertisedTopic=null;self['postMessage']({'cmd':'state','connected':![]});scheduleReconnect();};ws['onerror']=()=>{self['postMessage']({'cmd':'state','connected':![],'error':'WebSocket\x20连接错误'});};ws['onmessage']=_0x312c2b=>onSocketMessage(_0x312c2b['data']);}function wsSend(_0x410c27){if(!ws||ws['readyState']!==0x1)return![];try{ws['send'](JSON['stringify'](_0x410c27));return!![];}catch(_0x5217f7){return![];}}function advertise(){if(!connected||!cfg['topic'])return;wsSend({'op':'advertise','id':'advertise:'+cfg['topic'],'type':cfg['type'],'topic':cfg['topic'],'latch':![],'queue_size':0xa,'qos':{'history':'keep_last','depth':0xa,'reliability':'best_effort','durability':'volatile'}});advertisedTopic=cfg['topic'];}function unadvertise(){if(connected&&advertisedTopic){wsSend({'op':'unadvertise','topic':advertisedTopic,'id':'advertise:'+advertisedTopic});}advertisedTopic=null;}function queryDomainId(){if(!connected)return;domainIdSubscribed=!![];domainId=undefined;wsSend({'op':'subscribe','id':'domain-id','topic':DOMAIN_ID_TOPIC,'type':DOMAIN_ID_TYPE,'throttle_rate':0x7d0});if(domainIdTimer)clearTimeout(domainIdTimer);domainIdTimer=setTimeout(()=>{domainIdTimer=null;if(domainId===undefined){domainId=null;self['postMessage']({'cmd':'domainId','value':null});}},DOMAIN_ID_TIMEOUT_MS);}function stopDomainIdQuery(){domainIdSubscribed=![];if(domainIdTimer)clearTimeout(domainIdTimer);domainIdTimer=null;if(ws&&connected&&ws['readyState']===0x1){try{wsSend({'op':'unsubscribe','id':'domain-id','topic':DOMAIN_ID_TOPIC});}catch(_0x4d454b){}}domainId=undefined;}function onSocketMessage(_0xcf43d5){let _0x5881eb=null;try{_0x5881eb=JSON['parse'](_0xcf43d5);}catch(_0x58b8ba){return;}if(!domainIdSubscribed)return;if(!_0x5881eb||_0x5881eb['topic']!==DOMAIN_ID_TOPIC)return;const _0x1098c9=typeof _0x5881eb['msg']==='number'?_0x5881eb['msg']:_0x5881eb['msg']&&_0x5881eb['msg']['data'];if(typeof _0x1098c9!=='number')return;domainId=_0x1098c9;if(domainIdTimer)clearTimeout(domainIdTimer);domainIdTimer=null;self['postMessage']({'cmd':'domainId','value':_0x1098c9});}function startGrid(){stopGrid();rateWindow={'start':performance['now'](),'count':0x0};gridTimer=setInterval(onGrid,0x3e8/clampedRate());}function stopGrid(){if(gridTimer)clearInterval(gridTimer);gridTimer=null;}function onGrid(){if(!connected||!running)return;if(ws&&typeof ws['bufferedAmount']==='number'&&ws['bufferedAmount']>MAX_SOCKET_BUFFER){stats['dropped']++;stats['lastDrop']='socket-backlog';return;}const _0x534628=queue['shift']()||null;if(_0x534628){publish(_0x534628);}else if(stats['published']>0x0||pendingNeed>0x0){stats['underruns']++;}requestFrames();}function requestFrames(){if(!connected)return;const _0x4179d0=targetDepth()-queue['length']-pendingNeed-encodeInFlight;for(let _0x4de80f=0x0;_0x4de80f<_0x4179d0;_0x4de80f++){pendingNeed++;lastNeedAt=performance['now']();self['postMessage']({'cmd':'need'});}}function watchdogStall(_0x2ca755){if(!running)return;if(!connected){if(connectStartedAt>=0x0&&_0x2ca755-connectStartedAt>CONNECT_TIMEOUT_MS){stats['reconnects']++;stats['lastDrop']='connect-timeout';connectStartedAt=-0x1;closeSocket();connect(cfg['url']);}return;}if(pendingNeed>0x0&&_0x2ca755-lastNeedAt>NEED_TIMEOUT_MS){stats['stalled']+=pendingNeed;pendingNeed=0x0;stats['lastDrop']='need-timeout';requestFrames();}if(encodeInFlight>0x0&&_0x2ca755-lastEncodeAt>ENCODE_TIMEOUT_MS){stats['stalled']+=encodeInFlight;encodeInFlight=0x0;stats['lastDrop']='encode-timeout';requestFrames();}}function buildMessage(_0x107e95){const _0x66162b=Date['now']();return{'header':{'stamp':{'sec':Math['floor'](_0x66162b/0x3e8),'nanosec':_0x66162b%0x3e8*0xf4240},'frame_id':cfg['frameId']||''},'format':_0x107e95['format']||requestedEncoding()['format'],'data':_0x107e95['base64']};}function publish(_0x1e3cad){const _0x287762=wsSend({'op':'publish','topic':cfg['topic'],'msg':buildMessage(_0x1e3cad)});if(!_0x287762){stats['dropped']++;stats['lastDrop']='send';return;}stats['published']++;rateWindow['count']++;stats['payloadBytes']=_0x1e3cad['base64']['length'];stats['captureMs']=_0x1e3cad['captureMs']||0x0;stats['encodeMs']=_0x1e3cad['encodeMs']||0x0;stats['format']=_0x1e3cad['format']||'';if(cfg['preview']&&_0x1e3cad['previewBase64']){self['postMessage']({'cmd':'preview','base64':_0x1e3cad['previewBase64'],'mime':PREVIEW_MIME,'width':_0x1e3cad['width'],'height':_0x1e3cad['height'],'previewWidth':_0x1e3cad['pw'],'previewHeight':_0x1e3cad['ph'],'payloadBytes':_0x1e3cad['base64']['length'],'captureMs':_0x1e3cad['captureMs']||0x0});}}function reportStats(){const _0x915268=performance['now']();watchdogStall(_0x915268);const _0x210e68=_0x915268-rateWindow['start'];stats['rate']=_0x210e68>0x0?rateWindow['count']/(_0x210e68/0x3e8):0x0;rateWindow={'start':_0x915268,'count':0x0};stats['queue']=queue['length'];stats['depth']=targetDepth();stats['pendingNeed']=pendingNeed;stats['encodeInFlight']=encodeInFlight;stats['wsState']=ws?ws['readyState']:-0x1;stats['connected']=connected;stats['running']=running;self['postMessage']({'cmd':'stats',...stats,'target':clampedRate()});}async function encodeFrame(_0x4ccbbc){const {buffer:_0x11520c,width:_0x2d51f0,height:_0x599158,captureMs:_0x2625d4}=_0x4ccbbc;const _0x5a6813=performance['now']();try{if(!canvas)canvas=new OffscreenCanvas(_0x2d51f0,_0x599158);else if(canvas['width']!==_0x2d51f0||canvas['height']!==_0x599158){canvas['width']=_0x2d51f0;canvas['height']=_0x599158;}if(!ctx)ctx=canvas['getContext']('2d');ctx['putImageData'](new ImageData(new Uint8ClampedArray(_0x11520c),_0x2d51f0,_0x599158),0x0,0x0);const _0x2ab8e3=requestedEncoding();const _0x42fd50=await canvas['convertToBlob'](_0x2ab8e3['lossy']?{'type':_0x2ab8e3['mime'],'quality':Math['min'](0x1,Math['max'](0.01,(cfg['quality']||0x50)/0x64))}:{'type':_0x2ab8e3['mime']});const _0x3e88dd=new Uint8Array(await _0x42fd50['arrayBuffer']());const _0x3ee74c=formatOfBlob(_0x42fd50['type'],_0x2ab8e3['format']);if(_0x3ee74c!==_0x2ab8e3['format']){stats['lastDrop']='编码回落:'+_0x2ab8e3['format']+'->'+_0x3ee74c;}let _0xd0b97=null;let _0x18a905=0x0;let _0x1845e9=0x0;if(cfg['preview']){const _0x434b1b=Math['max'](0x50,Math['min'](0x280,cfg['previewWidth']||0x140));_0x18a905=Math['min'](_0x434b1b,_0x2d51f0);_0x1845e9=Math['max'](0x1,Math['round'](_0x599158*(_0x18a905/_0x2d51f0)));if(!previewCanvas)previewCanvas=new OffscreenCanvas(_0x18a905,_0x1845e9);else if(previewCanvas['width']!==_0x18a905||previewCanvas['height']!==_0x1845e9){previewCanvas['width']=_0x18a905;previewCanvas['height']=_0x1845e9;}if(!previewCtx)previewCtx=previewCanvas['getContext']('2d');previewCtx['drawImage'](canvas,0x0,0x0,_0x18a905,_0x1845e9);const _0x45f6ec=await previewCanvas['convertToBlob']({'type':PREVIEW_MIME,'quality':PREVIEW_QUALITY});_0xd0b97=bytesToBase64(new Uint8Array(await _0x45f6ec['arrayBuffer']()));}const _0x270f54=performance['now']()-_0x5a6813;produceSamples['push']((_0x2625d4||0x0)+_0x270f54);if(produceSamples['length']>0x8)produceSamples['shift']();queue['push']({'base64':bytesToBase64(_0x3e88dd),'format':_0x3ee74c,'previewBase64':_0xd0b97,'pw':_0x18a905,'ph':_0x1845e9,'width':_0x2d51f0,'height':_0x599158,'captureMs':_0x2625d4,'encodeMs':_0x270f54});if(queue['length']>MAX_QUEUE)queue['shift']();requestFrames();}catch(_0x16c4eb){stats['dropped']++;self['postMessage']({'cmd':'state','connected':connected,'error':'编码失败:\x20'+(_0x16c4eb&&_0x16c4eb['message']?_0x16c4eb['message']:String(_0x16c4eb))});}finally{try{self['postMessage']({'cmd':'buffer','buffer':_0x11520c},[_0x11520c]);}catch(_0x830969){stats['lastDrop']='buffer-return';}}}function applyConfig(_0x3165ff){Object['assign'](cfg,{'url':_0x3165ff['url']||cfg['url'],'topic':_0x3165ff['topic']||cfg['topic'],'type':_0x3165ff['type']||cfg['type'],'frameId':_0x3165ff['frameId']!==undefined?_0x3165ff['frameId']:cfg['frameId'],'rate':_0x3165ff['rate']||cfg['rate'],'format':_0x3165ff['format']||cfg['format'],'quality':_0x3165ff['quality']||cfg['quality'],'preview':_0x3165ff['preview']!==undefined?!!_0x3165ff['preview']:cfg['preview'],'previewWidth':_0x3165ff['previewWidth']||cfg['previewWidth']});}self['onmessage']=_0x208f48=>{const _0x3d10b1=_0x208f48['data']||{};switch(_0x3d10b1['cmd']){case'connect':{applyConfig(_0x3d10b1);connectionWanted=!![];retryDelay=0x7d0;if(reconnectTimer)clearTimeout(reconnectTimer);reconnectTimer=null;connectStartedAt=-0x1;if(!statsTimer)statsTimer=setInterval(reportStats,0x3e8);connect(cfg['url']);probeEncodings();break;}case'disconnect':{running=![];connectionWanted=![];connectStartedAt=-0x1;if(reconnectTimer)clearTimeout(reconnectTimer);reconnectTimer=null;stopGrid();if(statsTimer)clearInterval(statsTimer);statsTimer=null;unadvertise();closeSocket();queue=[];pendingNeed=0x0;encodeInFlight=0x0;self['postMessage']({'cmd':'state','connected':![]});break;}case'start':{applyConfig(_0x3d10b1);running=!![];connectionWanted=!![];retryDelay=0x7d0;if(reconnectTimer)clearTimeout(reconnectTimer);reconnectTimer=null;queue=[];produceSamples=[];pendingNeed=0x0;encodeInFlight=0x0;lastNeedAt=performance['now']();lastEncodeAt=lastNeedAt;connectStartedAt=-0x1;stats['published']=0x0;stats['dropped']=0x0;stats['underruns']=0x0;stats['stalled']=0x0;stats['reconnects']=0x0;stats['lastDrop']=null;if(statsTimer)clearInterval(statsTimer);statsTimer=setInterval(reportStats,0x3e8);connect(cfg['url']);if(connected)startGrid();probeEncodings();break;}case'config':{const _0x442249=clampedRate();const _0x3cde53=cfg['topic'];const _0x3e30f1=cfg['type'];['topic','type','frameId','rate','format','quality','preview','previewWidth']['forEach'](_0xf8392c=>{if(_0x3d10b1[_0xf8392c]!==undefined)cfg[_0xf8392c]=_0x3d10b1[_0xf8392c];});if(cfg['topic']!==_0x3cde53||cfg['type']!==_0x3e30f1){unadvertise();advertise();}if(clampedRate()!==_0x442249)startGrid();break;}case'stop':{running=![];stopGrid();queue=[];pendingNeed=0x0;encodeInFlight=0x0;break;}case'frame':{pendingNeed=Math['max'](0x0,pendingNeed-0x1);lastNeedAt=performance['now']();encodeInFlight++;lastEncodeAt=performance['now']();encodeFrame(_0x3d10b1)['finally'](()=>{encodeInFlight=Math['max'](0x0,encodeInFlight-0x1);});break;}case'noframe':{pendingNeed=Math['max'](0x0,pendingNeed-0x1);lastNeedAt=performance['now']();if(_0x3d10b1['reason'])stats['lastDrop']='no-frame:'+_0x3d10b1['reason'];break;}case'encodings':{if(typeof domainId==='number')self['postMessage']({'cmd':'domainId','value':domainId});probeEncodings();break;}default:break;}};
|
|
1
|
+
const PREVIEW_MIME='image/jpeg';const PREVIEW_QUALITY=0.7;const MAX_SOCKET_BUFFER=0x4*0x400*0x400;const MAX_QUEUE=0x3;const DOMAIN_ID_TOPIC='/robot_viewer/domain_id';const DOMAIN_ID_TYPE='std_msgs/msg/Int32';const DOMAIN_ID_TIMEOUT_MS=0x1388;const TOPIC_TYPE='sensor_msgs/msg/CompressedImage';const ENCODINGS=[{'format':'jpeg','mime':'image/jpeg','lossy':!![]},{'format':'png','mime':'image/png','lossy':![]},{'format':'webp','mime':'image/webp','lossy':!![]}];const MIME_TO_FORMAT={'image/jpeg':'jpeg','image/png':'png','image/webp':'webp'};const requestedEncoding=()=>ENCODINGS['find'](_0x4b771d=>_0x4b771d['format']===cfg['format'])||ENCODINGS[0x0];const formatOfBlob=(_0x221ca8,_0x4d2be4)=>MIME_TO_FORMAT[_0x221ca8]||_0x4d2be4;let encodingSupport=null;async function probeEncodings(){if(!encodingSupport){const _0x21d09a=[];try{const _0x33366a=new OffscreenCanvas(0x8,0x8);const _0x417f8d=_0x33366a['getContext']('2d');_0x417f8d['putImageData'](new ImageData(new Uint8ClampedArray(0x8*0x8*0x4),0x8,0x8),0x0,0x0);for(const _0x5ad1b6 of ENCODINGS){let _0x3cc882=![];try{const _0x8edd10=await _0x33366a['convertToBlob'](_0x5ad1b6['lossy']?{'type':_0x5ad1b6['mime'],'quality':0.8}:{'type':_0x5ad1b6['mime']});_0x3cc882=!!_0x8edd10&&_0x8edd10['type']===_0x5ad1b6['mime'];}catch(_0x26f11a){_0x3cc882=![];}_0x21d09a['push']({'format':_0x5ad1b6['format'],'supported':_0x3cc882});}}catch(_0x4b1a05){for(const _0x15a3fa of ENCODINGS)_0x21d09a['push']({'format':_0x15a3fa['format'],'supported':_0x15a3fa['format']==='jpeg'});}encodingSupport=_0x21d09a;}self['postMessage']({'cmd':'encodings','list':encodingSupport});return encodingSupport;}function bytesToBase64(_0x183cd7){const _0x584846=0x8000;let _0x376ca9='';for(let _0x498086=0x0;_0x498086<_0x183cd7['length'];_0x498086+=_0x584846){_0x376ca9+=String['fromCharCode']['apply'](null,_0x183cd7['subarray'](_0x498086,_0x498086+_0x584846));}return btoa(_0x376ca9);}let cfg={'url':'','topic':'','type':TOPIC_TYPE,'frameId':'','rate':0xa,'format':'jpeg','quality':0x50,'preview':![],'previewWidth':0x140};let ws=null;let connected=![];let running=![];let connectionWanted=![];let reconnectTimer=null;let retryDelay=0x7d0;let connectStartedAt=-0x1;let advertisedTopic=null;let gridTimer=null;let queue=[];let pendingNeed=0x0;let encodeInFlight=0x0;let lastNeedAt=0x0;let lastEncodeAt=0x0;let domainId=undefined;let domainIdTimer=null;let domainIdSubscribed=![];let canvas=null;let ctx=null;let previewCanvas=null;let previewCtx=null;let statsTimer=null;const NEED_TIMEOUT_MS=0x5dc;const ENCODE_TIMEOUT_MS=0x1388;const CONNECT_TIMEOUT_MS=0x1388;const stats={'published':0x0,'dropped':0x0,'underruns':0x0,'stalled':0x0,'reconnects':0x0,'payloadBytes':0x0,'encodeMs':0x0,'captureMs':0x0,'rate':0x0,'lastDrop':null};let rateWindow={'start':0x0,'count':0x0};let produceSamples=[];const clampedRate=()=>Math['max'](0x1,Math['min'](0x78,Math['round'](cfg['rate'])||0xa));const ROUND_TRIP_MS=0x3;const MIN_DEPTH=0x2;const targetDepth=()=>{const _0x7dec1=0x3e8/clampedRate();const _0x27795a=produceSamples['length']?Math['max'](...produceSamples):0x0;if(_0x27795a<=0x0)return MIN_DEPTH;const _0x9dde24=Math['ceil']((_0x27795a+ROUND_TRIP_MS)*1.15/_0x7dec1);return Math['min'](MAX_QUEUE,Math['max'](MIN_DEPTH,_0x9dde24));};function closeSocket(){stopDomainIdQuery();if(ws){const _0x5b17a9=ws;_0x5b17a9['onopen']=null;_0x5b17a9['onclose']=null;_0x5b17a9['onerror']=null;try{_0x5b17a9['close']();}catch(_0x343be9){}ws=null;}connected=![];advertisedTopic=null;}function scheduleReconnect(){if(!connectionWanted||reconnectTimer)return;reconnectTimer=setTimeout(()=>{reconnectTimer=null;if(running)connect(cfg['url']);},retryDelay);retryDelay=Math['min'](0x2710,retryDelay*0x2);}function connect(_0x4606d6){if(ws&&connected&&ws['readyState']===0x1&&cfg['url']===_0x4606d6){self['postMessage']({'cmd':'state','connected':!![],'reused':!![]});return;}closeSocket();if(!_0x4606d6){self['postMessage']({'cmd':'state','connected':![],'error':'缺少\x20rosbridge\x20地址'});return;}connectStartedAt=performance['now']();try{ws=new WebSocket(_0x4606d6);}catch(_0x2a3217){self['postMessage']({'cmd':'state','connected':![],'error':String(_0x2a3217&&_0x2a3217['message']||_0x2a3217)});scheduleReconnect();return;}ws['onopen']=()=>{connected=!![];connectStartedAt=-0x1;retryDelay=0x7d0;advertise();queryDomainId();if(running)startGrid();self['postMessage']({'cmd':'state','connected':!![]});};ws['onclose']=()=>{connected=![];connectStartedAt=-0x1;advertisedTopic=null;self['postMessage']({'cmd':'state','connected':![]});scheduleReconnect();};ws['onerror']=()=>{self['postMessage']({'cmd':'state','connected':![],'error':'WebSocket\x20连接错误'});};ws['onmessage']=_0x2add74=>onSocketMessage(_0x2add74['data']);}function wsSend(_0x275708){if(!ws||ws['readyState']!==0x1)return![];try{ws['send'](JSON['stringify'](_0x275708));return!![];}catch(_0x22c302){return![];}}function advertise(){if(!connected||!cfg['topic'])return;wsSend({'op':'advertise','id':'advertise:'+cfg['topic'],'type':cfg['type'],'topic':cfg['topic'],'latch':![],'queue_size':0xa,'qos':{'history':'keep_last','depth':0xa,'reliability':'best_effort','durability':'volatile'}});advertisedTopic=cfg['topic'];}function unadvertise(){if(connected&&advertisedTopic){wsSend({'op':'unadvertise','topic':advertisedTopic,'id':'advertise:'+advertisedTopic});}advertisedTopic=null;}function queryDomainId(){if(!connected)return;domainIdSubscribed=!![];domainId=undefined;wsSend({'op':'subscribe','id':'domain-id','topic':DOMAIN_ID_TOPIC,'type':DOMAIN_ID_TYPE,'throttle_rate':0x7d0});if(domainIdTimer)clearTimeout(domainIdTimer);domainIdTimer=setTimeout(()=>{domainIdTimer=null;if(domainId===undefined){domainId=null;self['postMessage']({'cmd':'domainId','value':null});}},DOMAIN_ID_TIMEOUT_MS);}function stopDomainIdQuery(){domainIdSubscribed=![];if(domainIdTimer)clearTimeout(domainIdTimer);domainIdTimer=null;if(ws&&connected&&ws['readyState']===0x1){try{wsSend({'op':'unsubscribe','id':'domain-id','topic':DOMAIN_ID_TOPIC});}catch(_0x5234af){}}domainId=undefined;}function onSocketMessage(_0x5b4213){let _0x554433=null;try{_0x554433=JSON['parse'](_0x5b4213);}catch(_0x3eeebb){return;}if(!domainIdSubscribed)return;if(!_0x554433||_0x554433['topic']!==DOMAIN_ID_TOPIC)return;const _0xc1c559=typeof _0x554433['msg']==='number'?_0x554433['msg']:_0x554433['msg']&&_0x554433['msg']['data'];if(typeof _0xc1c559!=='number')return;domainId=_0xc1c559;if(domainIdTimer)clearTimeout(domainIdTimer);domainIdTimer=null;self['postMessage']({'cmd':'domainId','value':_0xc1c559});}function startGrid(){stopGrid();rateWindow={'start':performance['now'](),'count':0x0};gridTimer=setInterval(onGrid,0x3e8/clampedRate());}function stopGrid(){if(gridTimer)clearInterval(gridTimer);gridTimer=null;}function onGrid(){if(!connected||!running)return;if(ws&&typeof ws['bufferedAmount']==='number'&&ws['bufferedAmount']>MAX_SOCKET_BUFFER){stats['dropped']++;stats['lastDrop']='socket-backlog';return;}const _0x188878=queue['shift']()||null;if(_0x188878){publish(_0x188878);}else if(stats['published']>0x0||pendingNeed>0x0){stats['underruns']++;}requestFrames();}function requestFrames(){if(!connected)return;const _0x4c9b79=targetDepth()-queue['length']-pendingNeed-encodeInFlight;for(let _0xce24ac=0x0;_0xce24ac<_0x4c9b79;_0xce24ac++){pendingNeed++;lastNeedAt=performance['now']();self['postMessage']({'cmd':'need'});}}function watchdogStall(_0x2588b7){if(!running)return;if(!connected){if(connectStartedAt>=0x0&&_0x2588b7-connectStartedAt>CONNECT_TIMEOUT_MS){stats['reconnects']++;stats['lastDrop']='connect-timeout';connectStartedAt=-0x1;closeSocket();connect(cfg['url']);}return;}if(pendingNeed>0x0&&_0x2588b7-lastNeedAt>NEED_TIMEOUT_MS){stats['stalled']+=pendingNeed;pendingNeed=0x0;stats['lastDrop']='need-timeout';requestFrames();}if(encodeInFlight>0x0&&_0x2588b7-lastEncodeAt>ENCODE_TIMEOUT_MS){stats['stalled']+=encodeInFlight;encodeInFlight=0x0;stats['lastDrop']='encode-timeout';requestFrames();}}function buildMessage(_0x5df382){const _0x4b9b80=Date['now']();return{'header':{'stamp':{'sec':Math['floor'](_0x4b9b80/0x3e8),'nanosec':_0x4b9b80%0x3e8*0xf4240},'frame_id':cfg['frameId']||''},'format':_0x5df382['format']||requestedEncoding()['format'],'data':_0x5df382['base64']};}function publish(_0x5e2e8e){const _0x1c4533=wsSend({'op':'publish','topic':cfg['topic'],'msg':buildMessage(_0x5e2e8e)});if(!_0x1c4533){stats['dropped']++;stats['lastDrop']='send';return;}stats['published']++;rateWindow['count']++;stats['payloadBytes']=_0x5e2e8e['base64']['length'];stats['captureMs']=_0x5e2e8e['captureMs']||0x0;stats['encodeMs']=_0x5e2e8e['encodeMs']||0x0;stats['format']=_0x5e2e8e['format']||'';if(cfg['preview']&&_0x5e2e8e['previewBase64']){self['postMessage']({'cmd':'preview','base64':_0x5e2e8e['previewBase64'],'mime':PREVIEW_MIME,'width':_0x5e2e8e['width'],'height':_0x5e2e8e['height'],'previewWidth':_0x5e2e8e['pw'],'previewHeight':_0x5e2e8e['ph'],'payloadBytes':_0x5e2e8e['base64']['length'],'captureMs':_0x5e2e8e['captureMs']||0x0});}}function reportStats(){const _0xf4f6cf=performance['now']();watchdogStall(_0xf4f6cf);const _0xce75ff=_0xf4f6cf-rateWindow['start'];stats['rate']=_0xce75ff>0x0?rateWindow['count']/(_0xce75ff/0x3e8):0x0;rateWindow={'start':_0xf4f6cf,'count':0x0};stats['queue']=queue['length'];stats['depth']=targetDepth();stats['pendingNeed']=pendingNeed;stats['encodeInFlight']=encodeInFlight;stats['wsState']=ws?ws['readyState']:-0x1;stats['connected']=connected;stats['running']=running;self['postMessage']({'cmd':'stats',...stats,'target':clampedRate()});}async function encodeFrame(_0x443592){const {buffer:_0x26291c,width:_0x4a3d24,height:_0x13cafd,captureMs:_0x537c3b}=_0x443592;const _0xdb75a1=performance['now']();try{if(!canvas)canvas=new OffscreenCanvas(_0x4a3d24,_0x13cafd);else if(canvas['width']!==_0x4a3d24||canvas['height']!==_0x13cafd){canvas['width']=_0x4a3d24;canvas['height']=_0x13cafd;}if(!ctx)ctx=canvas['getContext']('2d');ctx['putImageData'](new ImageData(new Uint8ClampedArray(_0x26291c),_0x4a3d24,_0x13cafd),0x0,0x0);const _0x799c92=requestedEncoding();const _0x4c7d9b=await canvas['convertToBlob'](_0x799c92['lossy']?{'type':_0x799c92['mime'],'quality':Math['min'](0x1,Math['max'](0.01,(cfg['quality']||0x50)/0x64))}:{'type':_0x799c92['mime']});const _0x32a812=new Uint8Array(await _0x4c7d9b['arrayBuffer']());const _0x4cace8=formatOfBlob(_0x4c7d9b['type'],_0x799c92['format']);if(_0x4cace8!==_0x799c92['format']){stats['lastDrop']='编码回落:'+_0x799c92['format']+'->'+_0x4cace8;}let _0x11f22d=null;let _0x87be05=0x0;let _0x299bc0=0x0;if(cfg['preview']){const _0x5e2164=Math['max'](0x50,Math['min'](0x280,cfg['previewWidth']||0x140));_0x87be05=Math['min'](_0x5e2164,_0x4a3d24);_0x299bc0=Math['max'](0x1,Math['round'](_0x13cafd*(_0x87be05/_0x4a3d24)));if(!previewCanvas)previewCanvas=new OffscreenCanvas(_0x87be05,_0x299bc0);else if(previewCanvas['width']!==_0x87be05||previewCanvas['height']!==_0x299bc0){previewCanvas['width']=_0x87be05;previewCanvas['height']=_0x299bc0;}if(!previewCtx)previewCtx=previewCanvas['getContext']('2d');previewCtx['drawImage'](canvas,0x0,0x0,_0x87be05,_0x299bc0);const _0x394db4=await previewCanvas['convertToBlob']({'type':PREVIEW_MIME,'quality':PREVIEW_QUALITY});_0x11f22d=bytesToBase64(new Uint8Array(await _0x394db4['arrayBuffer']()));}const _0x44b6f8=performance['now']()-_0xdb75a1;produceSamples['push']((_0x537c3b||0x0)+_0x44b6f8);if(produceSamples['length']>0x8)produceSamples['shift']();queue['push']({'base64':bytesToBase64(_0x32a812),'format':_0x4cace8,'previewBase64':_0x11f22d,'pw':_0x87be05,'ph':_0x299bc0,'width':_0x4a3d24,'height':_0x13cafd,'captureMs':_0x537c3b,'encodeMs':_0x44b6f8});if(queue['length']>MAX_QUEUE)queue['shift']();requestFrames();}catch(_0x56ae71){stats['dropped']++;self['postMessage']({'cmd':'state','connected':connected,'error':'编码失败:\x20'+(_0x56ae71&&_0x56ae71['message']?_0x56ae71['message']:String(_0x56ae71))});}finally{try{self['postMessage']({'cmd':'buffer','buffer':_0x26291c},[_0x26291c]);}catch(_0x5e8afe){stats['lastDrop']='buffer-return';}}}function applyConfig(_0x1349c1){Object['assign'](cfg,{'url':_0x1349c1['url']||cfg['url'],'topic':_0x1349c1['topic']||cfg['topic'],'type':_0x1349c1['type']||cfg['type'],'frameId':_0x1349c1['frameId']!==undefined?_0x1349c1['frameId']:cfg['frameId'],'rate':_0x1349c1['rate']||cfg['rate'],'format':_0x1349c1['format']||cfg['format'],'quality':_0x1349c1['quality']||cfg['quality'],'preview':_0x1349c1['preview']!==undefined?!!_0x1349c1['preview']:cfg['preview'],'previewWidth':_0x1349c1['previewWidth']||cfg['previewWidth']});}self['onmessage']=_0x238200=>{const _0x84e5e5=_0x238200['data']||{};switch(_0x84e5e5['cmd']){case'connect':{applyConfig(_0x84e5e5);connectionWanted=!![];retryDelay=0x7d0;if(reconnectTimer)clearTimeout(reconnectTimer);reconnectTimer=null;connectStartedAt=-0x1;if(!statsTimer)statsTimer=setInterval(reportStats,0x3e8);connect(cfg['url']);probeEncodings();break;}case'disconnect':{running=![];connectionWanted=![];connectStartedAt=-0x1;if(reconnectTimer)clearTimeout(reconnectTimer);reconnectTimer=null;stopGrid();if(statsTimer)clearInterval(statsTimer);statsTimer=null;unadvertise();closeSocket();queue=[];pendingNeed=0x0;encodeInFlight=0x0;self['postMessage']({'cmd':'state','connected':![]});break;}case'start':{applyConfig(_0x84e5e5);running=!![];connectionWanted=!![];retryDelay=0x7d0;if(reconnectTimer)clearTimeout(reconnectTimer);reconnectTimer=null;queue=[];produceSamples=[];pendingNeed=0x0;encodeInFlight=0x0;lastNeedAt=performance['now']();lastEncodeAt=lastNeedAt;connectStartedAt=-0x1;stats['published']=0x0;stats['dropped']=0x0;stats['underruns']=0x0;stats['stalled']=0x0;stats['reconnects']=0x0;stats['lastDrop']=null;if(statsTimer)clearInterval(statsTimer);statsTimer=setInterval(reportStats,0x3e8);connect(cfg['url']);if(connected)startGrid();probeEncodings();break;}case'config':{const _0x564318=clampedRate();const _0x4da94e=cfg['topic'];const _0x1fb281=cfg['type'];['topic','type','frameId','rate','format','quality','preview','previewWidth']['forEach'](_0x3fdda9=>{if(_0x84e5e5[_0x3fdda9]!==undefined)cfg[_0x3fdda9]=_0x84e5e5[_0x3fdda9];});if(cfg['topic']!==_0x4da94e||cfg['type']!==_0x1fb281){unadvertise();advertise();}if(clampedRate()!==_0x564318)startGrid();break;}case'stop':{running=![];stopGrid();queue=[];pendingNeed=0x0;encodeInFlight=0x0;break;}case'frame':{pendingNeed=Math['max'](0x0,pendingNeed-0x1);lastNeedAt=performance['now']();encodeInFlight++;lastEncodeAt=performance['now']();encodeFrame(_0x84e5e5)['finally'](()=>{encodeInFlight=Math['max'](0x0,encodeInFlight-0x1);});break;}case'noframe':{pendingNeed=Math['max'](0x0,pendingNeed-0x1);lastNeedAt=performance['now']();if(_0x84e5e5['reason'])stats['lastDrop']='no-frame:'+_0x84e5e5['reason'];break;}case'encodings':{if(typeof domainId==='number')self['postMessage']({'cmd':'domainId','value':domainId});probeEncodings();break;}default:break;}};
|
package/dist/heartbeat-worker.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
let intervalId=null;self['onmessage']=
|
|
1
|
+
let intervalId=null;self['onmessage']=_0x1c7c32=>{const {cmd:_0x27038b,rate:_0x1adc87}=_0x1c7c32['data'];if(_0x27038b==='start'){if(intervalId)clearInterval(intervalId);const _0x18cb24=Math['max'](0x1,Math['min'](_0x1adc87||0xc8,0x1f4));intervalId=setInterval(()=>{self['postMessage']('tick');},0x3e8/_0x18cb24);}else if(_0x27038b==='stop'){if(intervalId){clearInterval(intervalId);intervalId=null;}}};
|
package/dist/index.html
CHANGED
|
@@ -4069,7 +4069,7 @@
|
|
|
4069
4069
|
|
|
4070
4070
|
</style>
|
|
4071
4071
|
<!-- MATOMO_PLACEHOLDER -->
|
|
4072
|
-
<script type="module" crossorigin src="./assets/js/index-
|
|
4072
|
+
<script type="module" crossorigin src="./assets/js/index-90ddef80.js"></script>
|
|
4073
4073
|
<link rel="modulepreload" crossorigin href="./assets/js/three-9c891de0.js">
|
|
4074
4074
|
<link rel="modulepreload" crossorigin href="./assets/js/d3-2e308866.js">
|
|
4075
4075
|
<link rel="modulepreload" crossorigin href="./assets/js/codemirror-c3cec7b3.js">
|
|
@@ -4264,7 +4264,7 @@
|
|
|
4264
4264
|
|
|
4265
4265
|
<div id="floating-help-panel" class="floating-panel" style="display: none;">
|
|
4266
4266
|
<div class="floating-panel-header">
|
|
4267
|
-
<span data-i18n="helpTitle">Robot Viewer v1.1.
|
|
4267
|
+
<span data-i18n="helpTitle">Robot Viewer v1.1.3</span>
|
|
4268
4268
|
<button class="panel-close-btn" data-panel="floating-help-panel">✕</button>
|
|
4269
4269
|
</div>
|
|
4270
4270
|
<div class="floating-panel-content">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ioai/robot_viewer",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "Lightweight browser-based robot model viewer supporting URDF, MJCF, and USD formats",
|
|
5
5
|
"main": "bin/cli.js",
|
|
6
6
|
"bin": {
|
|
@@ -43,6 +43,9 @@
|
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
+
"express": "^4.18.2"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
46
49
|
"@babel/runtime": "^7.23.0",
|
|
47
50
|
"@codemirror/autocomplete": "^6.12.0",
|
|
48
51
|
"@codemirror/commands": "^6.3.3",
|
|
@@ -55,16 +58,13 @@
|
|
|
55
58
|
"@uiw/codemirror-theme-vscode": "^4.21.21",
|
|
56
59
|
"codemirror": "^6.0.1",
|
|
57
60
|
"d3": "^7.9.0",
|
|
58
|
-
"express": "^4.18.2",
|
|
59
61
|
"fflate": "^0.8.2",
|
|
60
62
|
"mujoco-js": "^0.0.7",
|
|
61
63
|
"roslib": "^1.3.0",
|
|
62
64
|
"three": "^0.163.0",
|
|
63
65
|
"uplot": "^1.6.32",
|
|
64
66
|
"urdf-loader": "^0.12.5",
|
|
65
|
-
"xacro-parser": "^0.3.11"
|
|
66
|
-
},
|
|
67
|
-
"devDependencies": {
|
|
67
|
+
"xacro-parser": "^0.3.11",
|
|
68
68
|
"javascript-obfuscator": "^5.6.0",
|
|
69
69
|
"terser": "^5.26.0",
|
|
70
70
|
"vite": "^4.5.0"
|
package/server/static-server.js
CHANGED
|
@@ -75,14 +75,46 @@ app.get('*', (req, res, next) => {
|
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
const server = app.listen(PORT, HOST, () => {
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
const localUrl = `http://127.0.0.1:${PORT}`;
|
|
79
|
+
const localhostUrl = `http://localhost:${PORT}`;
|
|
80
|
+
console.log('\n✅ IO Robot Viewer 已在本地启动');
|
|
81
|
+
console.log(` 请在浏览器访问: ${localUrl}`);
|
|
82
|
+
console.log(` 或访问: ${localhostUrl}`);
|
|
83
|
+
if (HOST === '0.0.0.0') {
|
|
84
|
+
console.log(` 监听地址: 0.0.0.0:${PORT}(允许局域网访问)`);
|
|
85
|
+
} else if (HOST !== '127.0.0.1' && HOST !== 'localhost') {
|
|
86
|
+
console.log(` 指定地址: http://${HOST}:${PORT}`);
|
|
87
|
+
}
|
|
88
|
+
console.log(' 按 Ctrl+C 停止服务\n');
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
server.on('error', (error) => {
|
|
92
|
+
if (error.code === 'EADDRINUSE') {
|
|
93
|
+
console.error(`\n✗ 端口 ${PORT} 已被占用,请更换端口,例如:--port ${PORT + 1}`);
|
|
94
|
+
} else {
|
|
95
|
+
console.error(`\n✗ 服务启动失败: ${error.message}`);
|
|
96
|
+
}
|
|
97
|
+
process.exit(1);
|
|
80
98
|
});
|
|
81
99
|
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
100
|
+
// Ctrl+C / SIGTERM 静默快速退出。先停止接收新请求,再关闭浏览器留下的
|
|
101
|
+
// keep-alive 连接;兜底定时器避免异常连接让终端长时间无法返回。
|
|
102
|
+
let shuttingDown = false;
|
|
103
|
+
function shutdown() {
|
|
104
|
+
if (shuttingDown) return;
|
|
105
|
+
shuttingDown = true;
|
|
106
|
+
|
|
107
|
+
const forceExit = setTimeout(() => process.exit(0), 500);
|
|
108
|
+
forceExit.unref();
|
|
109
|
+
|
|
110
|
+
server.close(() => {
|
|
111
|
+
clearTimeout(forceExit);
|
|
112
|
+
process.exit(0);
|
|
87
113
|
});
|
|
114
|
+
server.closeIdleConnections?.();
|
|
115
|
+
server.closeAllConnections?.();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
for (const signal of ['SIGTERM', 'SIGINT']) {
|
|
119
|
+
process.on(signal, shutdown);
|
|
88
120
|
}
|