Manual Control

Direct robot joint manipulation

{#if robot}
{#if robot.connectedSlaves.some((slave) => slave.name.includes("USB"))}

USB Robot Calibration

{#if robot.isCalibrated} OK {:else} Required {/if}
{#if !robot.isCalibrated}

1. Position robot to match rest pose

2. Click Calibrate when ready

{:else}
Calibrated at {robot.calibrationState.calibrationTime?.toLocaleTimeString()}
{/if}
{/if} {#if robot.manualControlEnabled}

Joint Controls

{robot.activeJoints.length}

Each joint can be moved independently using sliders. Values show virtual position (degrees) and real position in parentheses when available.

{#if robot.activeJoints.length === 0}

No active joints

{:else}
{#each robot.activeJoints as joint (joint.name)} {@const lower = joint.urdfJoint.limit?.lower != undefined ? (joint.urdfJoint.limit.lower * 180) / Math.PI : -180} {@const upper = joint.urdfJoint.limit?.upper != undefined ? (joint.urdfJoint.limit.upper * 180) / Math.PI : 180}
{joint.name}
{joint.virtualValue.toFixed(0)}° {#if joint.realValue !== undefined} ({joint.realValue.toFixed(0)}°) {/if}
{ const val = parseFloat((e.target as HTMLInputElement).value); robot.updateJointValue(joint.name, val); }} class="slider h-2 w-full cursor-pointer appearance-none rounded-lg bg-slate-600" />
{lower.toFixed(0)}° {upper.toFixed(0)}°
{/each}
{/if}
{:else}

Master Control Active

Master Control Active Robot controlled by: {robot.controlState.masterName}
Disconnect master to enable manual control.
{/if}
{/if}