Skydrone Rev D — Internals & Linkages

Rev D · 1.5 kg AUW · 760 mm fuselage · GoPro pod
Servo horns, pushrods & surfaces move live with sliders.
Servo placement from STL geometry. X-ray to see inside.
ballast 120–175 g · st 90
battery + heater · st 120
FC · GPS · pitot · st 240
ram-air pack · st 500
crow servos + surfaces
aileron servos + surfaces
ruddervator servos + surfaces
petal servo + torque shaft
canopy winch servos
chute pin servo
GoPro in cradle · st 715
CG · st 390 · 25% MAC
0°
0°
0°
0%
drag · wheel · shift-drag pan
ht(0x93c5fd,0.3);dl2.position.set(-500,600,-300);scene.add(dl2); // ── Camera / renderer ────────────────────────────────────────────────────────── const canvas=document.getElementById('c'); const renderer=new THREE.WebGLRenderer({canvas,antialias:true}); renderer.setPixelRatio(window.devicePixelRatio); const camera=new THREE.PerspectiveCamera(45,2,1,8000); let yaw=-0.8,pitch=0.3,dist=1250,panX=0,panZ=0,spin=false; function applyCam(){ camera.position.set(panX+dist*Math.cos(pitch)*Math.cos(yaw),dist*Math.cos(pitch)*Math.sin(yaw),panZ+dist*Math.sin(pitch)); camera.up.set(0,0,1);camera.lookAt(panX,0,panZ);} let drag=false,px=0,py=0,shifted=false; canvas.addEventListener('pointerdown',e=>{drag=true;px=e.clientX;py=e.clientY;shifted=e.shiftKey;spin=false;bSpin.classList.remove('on');}); window.addEventListener('pointerup',()=>drag=false); window.addEventListener('pointermove',e=>{ if(!drag)return;const dx=e.clientX-px,dy=e.clientY-py;px=e.clientX;py=e.clientY; if(shifted){panX-=dx*Math.sin(yaw);panZ+=dy;} else{yaw-=dx*0.008;pitch=Math.min(1.4,Math.max(-1.4,pitch+dy*0.008));}}); canvas.addEventListener('wheel',e=>{e.preventDefault();dist=Math.min(5000,Math.max(250,dist*(1+e.deltaY*0.001)));},{passive:false}); const bXray=document.getElementById('bXray'),bSpin=document.getElementById('bSpin'); let xray=true; bXray.onclick=()=>{xray=!xray;bXray.classList.toggle('on'); M.skin.opacity=xray?0.15:0.88;M.skin.depthWrite=!xray; M.wing.opacity=xray?0.45:0.92;}; bSpin.onclick=()=>{spin=!spin;bSpin.classList.toggle('on');}; function resize(){const w=canvas.clientWidth,h=canvas.clientHeight; if(canvas.width!==w||canvas.height!==h){renderer.setSize(w,h,false);camera.aspect=w/h;camera.updateProjectionMatrix();}} function tick(){resize();if(spin)yaw+=0.0026;applyCam();renderer.render(scene,camera);requestAnimationFrame(tick);} applyControls(); tick();