@ioai/robot_viewer 1.1.1 → 1.1.2

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.
@@ -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'](_0x18f059=>_0x18f059['format']===cfg['format'])||ENCODINGS[0x0];const formatOfBlob=(_0x1cdf63,_0x3dddad)=>MIME_TO_FORMAT[_0x1cdf63]||_0x3dddad;let encodingSupport=null;async function probeEncodings(){if(!encodingSupport){const _0x15483b=[];try{const _0x3f8cd0=new OffscreenCanvas(0x8,0x8);const _0x5bf113=_0x3f8cd0['getContext']('2d');_0x5bf113['putImageData'](new ImageData(new Uint8ClampedArray(0x8*0x8*0x4),0x8,0x8),0x0,0x0);for(const _0x27e78e of ENCODINGS){let _0x5833e5=![];try{const _0x4ab256=await _0x3f8cd0['convertToBlob'](_0x27e78e['lossy']?{'type':_0x27e78e['mime'],'quality':0.8}:{'type':_0x27e78e['mime']});_0x5833e5=!!_0x4ab256&&_0x4ab256['type']===_0x27e78e['mime'];}catch(_0x92927c){_0x5833e5=![];}_0x15483b['push']({'format':_0x27e78e['format'],'supported':_0x5833e5});}}catch(_0x2b6980){for(const _0xd82ff5 of ENCODINGS)_0x15483b['push']({'format':_0xd82ff5['format'],'supported':_0xd82ff5['format']==='jpeg'});}encodingSupport=_0x15483b;}self['postMessage']({'cmd':'encodings','list':encodingSupport});return encodingSupport;}function bytesToBase64(_0x434049){const _0x4499e8=0x8000;let _0x53a71c='';for(let _0xc65f4e=0x0;_0xc65f4e<_0x434049['length'];_0xc65f4e+=_0x4499e8){_0x53a71c+=String['fromCharCode']['apply'](null,_0x434049['subarray'](_0xc65f4e,_0xc65f4e+_0x4499e8));}return btoa(_0x53a71c);}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 _0x5c2904=0x3e8/clampedRate();const _0x3e9854=produceSamples['length']?Math['max'](...produceSamples):0x0;if(_0x3e9854<=0x0)return MIN_DEPTH;const _0x473b2c=Math['ceil']((_0x3e9854+ROUND_TRIP_MS)*1.15/_0x5c2904);return Math['min'](MAX_QUEUE,Math['max'](MIN_DEPTH,_0x473b2c));};function closeSocket(){stopDomainIdQuery();if(ws){const _0x11e06a=ws;_0x11e06a['onopen']=null;_0x11e06a['onclose']=null;_0x11e06a['onerror']=null;try{_0x11e06a['close']();}catch(_0x2c6c5){}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(_0x4ddf25){if(ws&&connected&&ws['readyState']===0x1&&cfg['url']===_0x4ddf25){self['postMessage']({'cmd':'state','connected':!![],'reused':!![]});return;}closeSocket();if(!_0x4ddf25){self['postMessage']({'cmd':'state','connected':![],'error':'缺少\x20rosbridge\x20地址'});return;}connectStartedAt=performance['now']();try{ws=new WebSocket(_0x4ddf25);}catch(_0x18676b){self['postMessage']({'cmd':'state','connected':![],'error':String(_0x18676b&&_0x18676b['message']||_0x18676b)});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']=_0x13a21e=>onSocketMessage(_0x13a21e['data']);}function wsSend(_0xd69d70){if(!ws||ws['readyState']!==0x1)return![];try{ws['send'](JSON['stringify'](_0xd69d70));return!![];}catch(_0x312abc){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(_0x5ad13e){}}domainId=undefined;}function onSocketMessage(_0x130fa5){let _0x4a4d43=null;try{_0x4a4d43=JSON['parse'](_0x130fa5);}catch(_0xa82860){return;}if(!domainIdSubscribed)return;if(!_0x4a4d43||_0x4a4d43['topic']!==DOMAIN_ID_TOPIC)return;const _0x260825=typeof _0x4a4d43['msg']==='number'?_0x4a4d43['msg']:_0x4a4d43['msg']&&_0x4a4d43['msg']['data'];if(typeof _0x260825!=='number')return;domainId=_0x260825;if(domainIdTimer)clearTimeout(domainIdTimer);domainIdTimer=null;self['postMessage']({'cmd':'domainId','value':_0x260825});}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 _0x53975c=queue['shift']()||null;if(_0x53975c){publish(_0x53975c);}else if(stats['published']>0x0||pendingNeed>0x0){stats['underruns']++;}requestFrames();}function requestFrames(){if(!connected)return;const _0x194044=targetDepth()-queue['length']-pendingNeed-encodeInFlight;for(let _0x54293e=0x0;_0x54293e<_0x194044;_0x54293e++){pendingNeed++;lastNeedAt=performance['now']();self['postMessage']({'cmd':'need'});}}function watchdogStall(_0x4e6d02){if(!running)return;if(!connected){if(connectStartedAt>=0x0&&_0x4e6d02-connectStartedAt>CONNECT_TIMEOUT_MS){stats['reconnects']++;stats['lastDrop']='connect-timeout';connectStartedAt=-0x1;closeSocket();connect(cfg['url']);}return;}if(pendingNeed>0x0&&_0x4e6d02-lastNeedAt>NEED_TIMEOUT_MS){stats['stalled']+=pendingNeed;pendingNeed=0x0;stats['lastDrop']='need-timeout';requestFrames();}if(encodeInFlight>0x0&&_0x4e6d02-lastEncodeAt>ENCODE_TIMEOUT_MS){stats['stalled']+=encodeInFlight;encodeInFlight=0x0;stats['lastDrop']='encode-timeout';requestFrames();}}function buildMessage(_0x4fda6b){const _0xc7e127=Date['now']();return{'header':{'stamp':{'sec':Math['floor'](_0xc7e127/0x3e8),'nanosec':_0xc7e127%0x3e8*0xf4240},'frame_id':cfg['frameId']||''},'format':_0x4fda6b['format']||requestedEncoding()['format'],'data':_0x4fda6b['base64']};}function publish(_0x42c567){const _0x1e2305=wsSend({'op':'publish','topic':cfg['topic'],'msg':buildMessage(_0x42c567)});if(!_0x1e2305){stats['dropped']++;stats['lastDrop']='send';return;}stats['published']++;rateWindow['count']++;stats['payloadBytes']=_0x42c567['base64']['length'];stats['captureMs']=_0x42c567['captureMs']||0x0;stats['encodeMs']=_0x42c567['encodeMs']||0x0;stats['format']=_0x42c567['format']||'';if(cfg['preview']&&_0x42c567['previewBase64']){self['postMessage']({'cmd':'preview','base64':_0x42c567['previewBase64'],'mime':PREVIEW_MIME,'width':_0x42c567['width'],'height':_0x42c567['height'],'previewWidth':_0x42c567['pw'],'previewHeight':_0x42c567['ph'],'payloadBytes':_0x42c567['base64']['length'],'captureMs':_0x42c567['captureMs']||0x0});}}function reportStats(){const _0x19731c=performance['now']();watchdogStall(_0x19731c);const _0xf682e0=_0x19731c-rateWindow['start'];stats['rate']=_0xf682e0>0x0?rateWindow['count']/(_0xf682e0/0x3e8):0x0;rateWindow={'start':_0x19731c,'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(_0xf50773){const {buffer:_0x179b43,width:_0x5958dc,height:_0x5f52dc,captureMs:_0x54e1c6}=_0xf50773;const _0x18c4f7=performance['now']();try{if(!canvas)canvas=new OffscreenCanvas(_0x5958dc,_0x5f52dc);else if(canvas['width']!==_0x5958dc||canvas['height']!==_0x5f52dc){canvas['width']=_0x5958dc;canvas['height']=_0x5f52dc;}if(!ctx)ctx=canvas['getContext']('2d');ctx['putImageData'](new ImageData(new Uint8ClampedArray(_0x179b43),_0x5958dc,_0x5f52dc),0x0,0x0);const _0x79a8a0=requestedEncoding();const _0x1eab18=await canvas['convertToBlob'](_0x79a8a0['lossy']?{'type':_0x79a8a0['mime'],'quality':Math['min'](0x1,Math['max'](0.01,(cfg['quality']||0x50)/0x64))}:{'type':_0x79a8a0['mime']});const _0x383bb5=new Uint8Array(await _0x1eab18['arrayBuffer']());const _0x3eccc2=formatOfBlob(_0x1eab18['type'],_0x79a8a0['format']);if(_0x3eccc2!==_0x79a8a0['format']){stats['lastDrop']='编码回落:'+_0x79a8a0['format']+'->'+_0x3eccc2;}let _0x51dbcc=null;let _0x3310ad=0x0;let _0x23f07f=0x0;if(cfg['preview']){const _0x256adb=Math['max'](0x50,Math['min'](0x280,cfg['previewWidth']||0x140));_0x3310ad=Math['min'](_0x256adb,_0x5958dc);_0x23f07f=Math['max'](0x1,Math['round'](_0x5f52dc*(_0x3310ad/_0x5958dc)));if(!previewCanvas)previewCanvas=new OffscreenCanvas(_0x3310ad,_0x23f07f);else if(previewCanvas['width']!==_0x3310ad||previewCanvas['height']!==_0x23f07f){previewCanvas['width']=_0x3310ad;previewCanvas['height']=_0x23f07f;}if(!previewCtx)previewCtx=previewCanvas['getContext']('2d');previewCtx['drawImage'](canvas,0x0,0x0,_0x3310ad,_0x23f07f);const _0x393e2c=await previewCanvas['convertToBlob']({'type':PREVIEW_MIME,'quality':PREVIEW_QUALITY});_0x51dbcc=bytesToBase64(new Uint8Array(await _0x393e2c['arrayBuffer']()));}const _0x3d9880=performance['now']()-_0x18c4f7;produceSamples['push']((_0x54e1c6||0x0)+_0x3d9880);if(produceSamples['length']>0x8)produceSamples['shift']();queue['push']({'base64':bytesToBase64(_0x383bb5),'format':_0x3eccc2,'previewBase64':_0x51dbcc,'pw':_0x3310ad,'ph':_0x23f07f,'width':_0x5958dc,'height':_0x5f52dc,'captureMs':_0x54e1c6,'encodeMs':_0x3d9880});if(queue['length']>MAX_QUEUE)queue['shift']();requestFrames();}catch(_0x51b40a){stats['dropped']++;self['postMessage']({'cmd':'state','connected':connected,'error':'编码失败:\x20'+(_0x51b40a&&_0x51b40a['message']?_0x51b40a['message']:String(_0x51b40a))});}finally{try{self['postMessage']({'cmd':'buffer','buffer':_0x179b43},[_0x179b43]);}catch(_0x4bbd72){stats['lastDrop']='buffer-return';}}}function applyConfig(_0x5409fd){Object['assign'](cfg,{'url':_0x5409fd['url']||cfg['url'],'topic':_0x5409fd['topic']||cfg['topic'],'type':_0x5409fd['type']||cfg['type'],'frameId':_0x5409fd['frameId']!==undefined?_0x5409fd['frameId']:cfg['frameId'],'rate':_0x5409fd['rate']||cfg['rate'],'format':_0x5409fd['format']||cfg['format'],'quality':_0x5409fd['quality']||cfg['quality'],'preview':_0x5409fd['preview']!==undefined?!!_0x5409fd['preview']:cfg['preview'],'previewWidth':_0x5409fd['previewWidth']||cfg['previewWidth']});}self['onmessage']=_0x571913=>{const _0x46d2a0=_0x571913['data']||{};switch(_0x46d2a0['cmd']){case'connect':{applyConfig(_0x46d2a0);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(_0x46d2a0);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 _0x1b403a=clampedRate();const _0x50a588=cfg['topic'];const _0x3e6223=cfg['type'];['topic','type','frameId','rate','format','quality','preview','previewWidth']['forEach'](_0x19023f=>{if(_0x46d2a0[_0x19023f]!==undefined)cfg[_0x19023f]=_0x46d2a0[_0x19023f];});if(cfg['topic']!==_0x50a588||cfg['type']!==_0x3e6223){unadvertise();advertise();}if(clampedRate()!==_0x1b403a)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(_0x46d2a0)['finally'](()=>{encodeInFlight=Math['max'](0x0,encodeInFlight-0x1);});break;}case'noframe':{pendingNeed=Math['max'](0x0,pendingNeed-0x1);lastNeedAt=performance['now']();if(_0x46d2a0['reason'])stats['lastDrop']='no-frame:'+_0x46d2a0['reason'];break;}case'encodings':{if(typeof domainId==='number')self['postMessage']({'cmd':'domainId','value':domainId});probeEncodings();break;}default:break;}};
@@ -1 +1 @@
1
- let intervalId=null;self['onmessage']=_0x150b3f=>{const {cmd:_0xa9fa09,rate:_0x3998d6}=_0x150b3f['data'];if(_0xa9fa09==='start'){if(intervalId)clearInterval(intervalId);const _0x2afbcf=Math['max'](0x1,Math['min'](_0x3998d6||0xc8,0x1f4));intervalId=setInterval(()=>{self['postMessage']('tick');},0x3e8/_0x2afbcf);}else if(_0xa9fa09==='stop'){if(intervalId){clearInterval(intervalId);intervalId=null;}}};
1
+ let intervalId=null;self['onmessage']=_0x60997=>{const {cmd:_0x3e64c1,rate:_0x149300}=_0x60997['data'];if(_0x3e64c1==='start'){if(intervalId)clearInterval(intervalId);const _0x3a99db=Math['max'](0x1,Math['min'](_0x149300||0xc8,0x1f4));intervalId=setInterval(()=>{self['postMessage']('tick');},0x3e8/_0x3a99db);}else if(_0x3e64c1==='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-2e5294e6.js"></script>
4072
+ <script type="module" crossorigin src="./assets/js/index-56e94ce5.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.1</span>
4267
+ <span data-i18n="helpTitle">Robot Viewer v1.1.2</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.1",
3
+ "version": "1.1.2",
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"
@@ -75,8 +75,26 @@ app.get('*', (req, res, next) => {
75
75
  });
76
76
 
77
77
  const server = app.listen(PORT, HOST, () => {
78
- console.log(`io_robot_viewer 生产服务运行在 http://${HOST}:${PORT}`);
79
- console.log(` 静态目录: ${DIST_DIR}`);
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
100
  // 容器/systemd 里用 SIGTERM 停服,需要优雅关闭,否则连接会被硬断