@operato/scene-manufacturing 10.0.0-beta.22 → 10.0.0-beta.28
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/dist/robot-arm.d.ts +53 -39
- package/dist/robot-arm.js +88 -65
- package/dist/robot-arm.js.map +1 -1
- package/dist/templates/index.d.ts +9 -0
- package/dist/templates/robot-arm.d.ts +9 -0
- package/dist/templates/robot-arm.js +12 -5
- package/dist/templates/robot-arm.js.map +1 -1
- package/icons/robot-arm.png +0 -0
- package/package.json +3 -3
- package/icons/tact-timer.png +0 -0
package/dist/robot-arm.d.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
2
|
import { Component, ComponentNature, RealObject } from '@hatiolab/things-scene';
|
|
3
|
-
import { type Alignment, type Heights, type LegendBinding, type PlacementArchetype } from '@operato/scene-base';
|
|
3
|
+
import { type Alignment, type Heights, type LegendBinding, type MoveOptions, type PlacementArchetype } from '@operato/scene-base';
|
|
4
4
|
export type RobotArmStatus = 'idle' | 'moving' | 'gripping' | 'warn' | 'error';
|
|
5
|
-
declare const Base: typeof Component
|
|
5
|
+
declare const Base: typeof Component & {
|
|
6
|
+
new (...args: any[]): Component & {
|
|
7
|
+
isMover: boolean;
|
|
8
|
+
pick(carrier: Component, options?: MoveOptions): Promise<void>;
|
|
9
|
+
place(carrier: Component, holder: Component, options?: MoveOptions): Promise<void>;
|
|
10
|
+
pickAndPlace(carrier: Component, holder: Component, options?: MoveOptions): Promise<void>;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
6
13
|
export default class RobotArm extends Base {
|
|
7
14
|
static legends: Record<string, LegendBinding>;
|
|
8
15
|
/**
|
|
@@ -89,40 +96,56 @@ export default class RobotArm extends Base {
|
|
|
89
96
|
};
|
|
90
97
|
} | undefined;
|
|
91
98
|
/**
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* Movement sequence:
|
|
99
|
+
* Pick: TCP descends vertically onto the carrier's top face, gripper
|
|
100
|
+
* closes, carrier becomes our child.
|
|
95
101
|
*
|
|
96
102
|
* 1. TCP → APPROACH above pick (carrier's xy, +clearance in world Y)
|
|
97
103
|
* 2. TCP → pick (descend straight down to carrier's top face)
|
|
98
104
|
* 3. close gripper + reparent(carrier → this)
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* `localPosition.z = +halfDepth` keeps the carrier's top at TCP
|
|
114
|
-
* origin during transit — exact, no offset drift.
|
|
115
|
-
* - Place: TCP lands at where the carrier's top WILL BE after the
|
|
116
|
-
* drop, so the carrier lands with its bottom on the placeHolder's
|
|
117
|
-
* attach surface (top-of-pad for Spot, etc.). Computed as
|
|
118
|
-
* `placeHolder.attachFrame.world.y + carrier.depth`.
|
|
105
|
+
*
|
|
106
|
+
* The approach waypoint exists so the FINAL leg is a clean vertical
|
|
107
|
+
* descent — the gripper enters the carrier from straight above, not a
|
|
108
|
+
* sideways sweep that could clip or grab at a wrong angle.
|
|
109
|
+
*
|
|
110
|
+
* Pose resolution: TCP lands on the CARRIER'S TOP FACE (carrier.world.y +
|
|
111
|
+
* carrier.depth/2). After grip, `attachPointFor`'s `localPosition.z =
|
|
112
|
+
* +halfDepth` keeps the carrier's top at TCP origin during transit —
|
|
113
|
+
* exact, no offset drift.
|
|
114
|
+
*
|
|
115
|
+
* Each waypoint includes the carrier's world yaw so IK can spin joint 5
|
|
116
|
+
* (tool roll) to align the gripper's "side" with the carrier's. Without
|
|
117
|
+
* it, reparent at pick instantly snaps the carrier to the gripper's
|
|
118
|
+
* axis, visibly twisting it 0° → up to 360° in one frame.
|
|
119
119
|
*
|
|
120
120
|
* @param options.approachClearance Vertical offset (world units)
|
|
121
|
-
* between
|
|
122
|
-
* (default 10) — just enough to make the final leg a clean
|
|
123
|
-
* straight-down vertical descent. Bump it for tall carriers or
|
|
124
|
-
* crowded scenes.
|
|
121
|
+
* between approach and pick targets. Default 10.
|
|
125
122
|
* @param options.timeoutMs Per-segment IK timeout (default 15000ms).
|
|
123
|
+
* @param options.reparentDuration Animation duration for reparent (default 800ms).
|
|
124
|
+
*/
|
|
125
|
+
pick(carrier: Component, options?: MoveOptions): Promise<void>;
|
|
126
|
+
/**
|
|
127
|
+
* Place: TCP descends vertically over the holder, gripper opens,
|
|
128
|
+
* carrier becomes the holder's child.
|
|
129
|
+
*
|
|
130
|
+
* 1. TCP → APPROACH above place (carrier's xy, +clearance)
|
|
131
|
+
* 2. TCP → place (descend straight down to drop point)
|
|
132
|
+
* 3. open gripper + reparent(carrier → holder)
|
|
133
|
+
*
|
|
134
|
+
* Pose resolution: TCP lands at where the carrier's top WILL BE after
|
|
135
|
+
* the drop, so the carrier lands with its bottom on the holder's attach
|
|
136
|
+
* surface. Computed as `holder.attachFrame.world.y + carrier.depth` (so
|
|
137
|
+
* yOffset = carrierDepth, not halfDepth like pick).
|
|
138
|
+
*
|
|
139
|
+
* @see pick — same option semantics.
|
|
140
|
+
*/
|
|
141
|
+
place(carrier: Component, holder: Component, options?: MoveOptions): Promise<void>;
|
|
142
|
+
/**
|
|
143
|
+
* `pickAndPlace` is inherited from the `Mover` mixin default — runs
|
|
144
|
+
* `pick(carrier)` then `place(carrier, holder)` sequentially. The
|
|
145
|
+
* decomposition is safe: the carrier's world position only matters
|
|
146
|
+
* during pick (carrier-relative waypoints), and after pick the carrier
|
|
147
|
+
* is the TCP's child (so re-querying it would chase its own tail —
|
|
148
|
+
* which we don't, since place uses holder-relative waypoints only).
|
|
126
149
|
*
|
|
127
150
|
* @example
|
|
128
151
|
* ```ts
|
|
@@ -130,17 +153,8 @@ export default class RobotArm extends Base {
|
|
|
130
153
|
* await robotArm.pnp(parcel, palletA, { approachClearance: 30 })
|
|
131
154
|
* ```
|
|
132
155
|
*/
|
|
133
|
-
pickAndPlace(carrier: Component, placeHolder: Component, options?: {
|
|
134
|
-
timeoutMs?: number;
|
|
135
|
-
reparentDuration?: number;
|
|
136
|
-
approachClearance?: number;
|
|
137
|
-
}): Promise<void>;
|
|
138
156
|
/** Short alias for `pickAndPlace`. Same arguments, same behavior. */
|
|
139
|
-
pnp(carrier: Component, placeHolder: Component, options?:
|
|
140
|
-
timeoutMs?: number;
|
|
141
|
-
reparentDuration?: number;
|
|
142
|
-
approachClearance?: number;
|
|
143
|
-
}): Promise<void>;
|
|
157
|
+
pnp(carrier: Component, placeHolder: Component, options?: MoveOptions): Promise<void>;
|
|
144
158
|
/**
|
|
145
159
|
* Resolve a TCP position in this arm's chain-local frame.
|
|
146
160
|
*
|
package/dist/robot-arm.js
CHANGED
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
*/
|
|
34
34
|
import { __decorate } from "tslib";
|
|
35
35
|
import * as THREE from 'three';
|
|
36
|
-
import {
|
|
37
|
-
import { CarrierHolder, Legendable, Placeable } from '@operato/scene-base';
|
|
36
|
+
import { ContainerAbstract, sceneComponent } from '@hatiolab/things-scene';
|
|
37
|
+
import { CarrierHolder, Legendable, Mover, Placeable } from '@operato/scene-base';
|
|
38
38
|
import { RobotArm3D } from './robot-arm-3d.js';
|
|
39
39
|
import { CHAIN_PRESETS } from './robot-arm-styles.js';
|
|
40
40
|
const BODY_LEGEND = {
|
|
@@ -119,12 +119,28 @@ const STATIC_PROPERTIES = [
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
];
|
|
122
|
-
// CarrierHolder +
|
|
123
|
-
// (addComponent / reparent / events) AND CarrierHolder's
|
|
124
|
-
// hook. CarrierHolder mixin alone only publishes the attach
|
|
125
|
-
// doesn't add child management. RectPath(Shape) was wrong here —
|
|
126
|
-
// a leaf so reparent silently failed.
|
|
127
|
-
|
|
122
|
+
// CarrierHolder + ContainerAbstract: the arm needs the container's child-list
|
|
123
|
+
// machinery (addComponent / reparent / events) AND CarrierHolder's
|
|
124
|
+
// attachPointFor hook. CarrierHolder mixin alone only publishes the attach
|
|
125
|
+
// policy; it doesn't add child management. RectPath(Shape) was wrong here —
|
|
126
|
+
// Shape is a leaf so reparent silently failed. ContainerAbstract provides
|
|
127
|
+
// the missing piece.
|
|
128
|
+
//
|
|
129
|
+
// `ContainerAbstract` (not `Container`) — Container = MixinHTMLElement(ContainerAbstract),
|
|
130
|
+
// which forces `isHTMLElement(): true` and trips the 3D pipeline's
|
|
131
|
+
// addObject DOM-skip gate. Robot arm exists purely in the 3D scene graph
|
|
132
|
+
// (URDF/IK joints, no DOM overlay), so the bare logical container is correct.
|
|
133
|
+
//
|
|
134
|
+
// Mover wraps the chain to publish pick/place/pickAndPlace primitives. It
|
|
135
|
+
// must sit OUTSIDE CarrierHolder because Mover's defaults call this.reparent,
|
|
136
|
+
// which CarrierHolder provides (overrides the base ContainerAbstract
|
|
137
|
+
// version with the attach-frame-aware variant).
|
|
138
|
+
//
|
|
139
|
+
// The instance type cast surfaces Mover's API on `this` so subclass
|
|
140
|
+
// `override` keywords compile and `this.pickAndPlace(...)` resolves —
|
|
141
|
+
// without it, the `as unknown as typeof Component` cast erases all
|
|
142
|
+
// mixin contributions to the static side.
|
|
143
|
+
const Base = Mover(CarrierHolder(Legendable(Placeable(ContainerAbstract))));
|
|
128
144
|
let RobotArm = class RobotArm extends Base {
|
|
129
145
|
static legends = {
|
|
130
146
|
bodyColor: { from: 'status', legend: BODY_LEGEND },
|
|
@@ -318,92 +334,99 @@ let RobotArm = class RobotArm extends Base {
|
|
|
318
334
|
};
|
|
319
335
|
}
|
|
320
336
|
/**
|
|
321
|
-
*
|
|
322
|
-
*
|
|
323
|
-
* Movement sequence:
|
|
337
|
+
* Pick: TCP descends vertically onto the carrier's top face, gripper
|
|
338
|
+
* closes, carrier becomes our child.
|
|
324
339
|
*
|
|
325
340
|
* 1. TCP → APPROACH above pick (carrier's xy, +clearance in world Y)
|
|
326
341
|
* 2. TCP → pick (descend straight down to carrier's top face)
|
|
327
342
|
* 3. close gripper + reparent(carrier → this)
|
|
328
|
-
* 4. TCP → APPROACH above place (carries the carrier up & over —
|
|
329
|
-
* the IK path naturally lifts then descends to the new approach
|
|
330
|
-
* pose since the approach is higher than pick)
|
|
331
|
-
* 5. TCP → place (descend straight down to drop point)
|
|
332
|
-
* 6. open gripper + reparent(carrier → placeHolder)
|
|
333
343
|
*
|
|
334
|
-
* The
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
*
|
|
344
|
+
* The approach waypoint exists so the FINAL leg is a clean vertical
|
|
345
|
+
* descent — the gripper enters the carrier from straight above, not a
|
|
346
|
+
* sideways sweep that could clip or grab at a wrong angle.
|
|
347
|
+
*
|
|
348
|
+
* Pose resolution: TCP lands on the CARRIER'S TOP FACE (carrier.world.y +
|
|
349
|
+
* carrier.depth/2). After grip, `attachPointFor`'s `localPosition.z =
|
|
350
|
+
* +halfDepth` keeps the carrier's top at TCP origin during transit —
|
|
351
|
+
* exact, no offset drift.
|
|
338
352
|
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
* origin during transit — exact, no offset drift.
|
|
344
|
-
* - Place: TCP lands at where the carrier's top WILL BE after the
|
|
345
|
-
* drop, so the carrier lands with its bottom on the placeHolder's
|
|
346
|
-
* attach surface (top-of-pad for Spot, etc.). Computed as
|
|
347
|
-
* `placeHolder.attachFrame.world.y + carrier.depth`.
|
|
353
|
+
* Each waypoint includes the carrier's world yaw so IK can spin joint 5
|
|
354
|
+
* (tool roll) to align the gripper's "side" with the carrier's. Without
|
|
355
|
+
* it, reparent at pick instantly snaps the carrier to the gripper's
|
|
356
|
+
* axis, visibly twisting it 0° → up to 360° in one frame.
|
|
348
357
|
*
|
|
349
358
|
* @param options.approachClearance Vertical offset (world units)
|
|
350
|
-
* between
|
|
351
|
-
* (default 10) — just enough to make the final leg a clean
|
|
352
|
-
* straight-down vertical descent. Bump it for tall carriers or
|
|
353
|
-
* crowded scenes.
|
|
359
|
+
* between approach and pick targets. Default 10.
|
|
354
360
|
* @param options.timeoutMs Per-segment IK timeout (default 15000ms).
|
|
355
|
-
*
|
|
356
|
-
* @example
|
|
357
|
-
* ```ts
|
|
358
|
-
* await robotArm.pickAndPlace(box, spotB)
|
|
359
|
-
* await robotArm.pnp(parcel, palletA, { approachClearance: 30 })
|
|
360
|
-
* ```
|
|
361
|
+
* @param options.reparentDuration Animation duration for reparent (default 800ms).
|
|
361
362
|
*/
|
|
362
|
-
async
|
|
363
|
+
async pick(carrier, options = {}) {
|
|
363
364
|
const timeoutMs = options.timeoutMs ?? 15000;
|
|
364
365
|
const reparentDuration = options.reparentDuration ?? 800;
|
|
366
|
+
const clearance = options.approachClearance ?? 10;
|
|
365
367
|
// Read carrier height via _realObject.effectiveDepth — `state.depth`
|
|
366
368
|
// is often not explicitly set (carriers like Box rely on
|
|
367
369
|
// `static defaultDepth`), and reading state alone returns 0, which
|
|
368
370
|
// collapses every Y offset and drives the gripper into the carrier's
|
|
369
371
|
// volumetric center instead of its top face.
|
|
370
372
|
const carrierDepth = resolveDepth(carrier);
|
|
371
|
-
const clearance = options.approachClearance ?? 10;
|
|
372
|
-
// Pre-compute all waypoints once. Recomputing mid-sequence would
|
|
373
|
-
// pick up the carrier's NEW world position once it's parented to
|
|
374
|
-
// the gripper (= TCP itself), causing a chase-your-tail loop.
|
|
375
|
-
//
|
|
376
|
-
// Each waypoint includes the target's world yaw so the IK can spin
|
|
377
|
-
// joint 5 (tool roll) to align the gripper's "side" with the
|
|
378
|
-
// carrier's — without it, reparent at pick instantly snaps the
|
|
379
|
-
// carrier to the gripper's axis, visibly twisting it 0° → up to
|
|
380
|
-
// 360° in one frame. Same problem inverted at place.
|
|
381
373
|
const halfDepth = carrierDepth / 2;
|
|
382
|
-
const
|
|
383
|
-
const
|
|
384
|
-
const
|
|
385
|
-
|
|
386
|
-
const placeTarget = this._targetFor(placeHolder, carrierDepth, placeYaw); // top-of-carrier after drop
|
|
387
|
-
const placeApproach = this._targetFor(placeHolder, carrierDepth + clearance, placeYaw);
|
|
388
|
-
// 1. Approach above pick.
|
|
389
|
-
this.set('target', pickApproach);
|
|
374
|
+
const yaw = this._yawOf(carrier);
|
|
375
|
+
const target = this._targetFor(carrier, halfDepth, yaw);
|
|
376
|
+
const approach = this._targetFor(carrier, halfDepth + clearance, yaw);
|
|
377
|
+
this.set('target', approach);
|
|
390
378
|
await waitForTcpReached(this, timeoutMs);
|
|
391
|
-
|
|
392
|
-
this.set('target', pickTarget);
|
|
379
|
+
this.set('target', target);
|
|
393
380
|
await waitForTcpReached(this, timeoutMs);
|
|
394
381
|
this.reparent?.(carrier, { animated: true, duration: reparentDuration });
|
|
395
382
|
this.set('gripper', { ...(this.state.gripper ?? {}), state: 1 });
|
|
396
383
|
await sleep(reparentDuration);
|
|
397
|
-
|
|
398
|
-
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Place: TCP descends vertically over the holder, gripper opens,
|
|
387
|
+
* carrier becomes the holder's child.
|
|
388
|
+
*
|
|
389
|
+
* 1. TCP → APPROACH above place (carrier's xy, +clearance)
|
|
390
|
+
* 2. TCP → place (descend straight down to drop point)
|
|
391
|
+
* 3. open gripper + reparent(carrier → holder)
|
|
392
|
+
*
|
|
393
|
+
* Pose resolution: TCP lands at where the carrier's top WILL BE after
|
|
394
|
+
* the drop, so the carrier lands with its bottom on the holder's attach
|
|
395
|
+
* surface. Computed as `holder.attachFrame.world.y + carrier.depth` (so
|
|
396
|
+
* yOffset = carrierDepth, not halfDepth like pick).
|
|
397
|
+
*
|
|
398
|
+
* @see pick — same option semantics.
|
|
399
|
+
*/
|
|
400
|
+
async place(carrier, holder, options = {}) {
|
|
401
|
+
const timeoutMs = options.timeoutMs ?? 15000;
|
|
402
|
+
const reparentDuration = options.reparentDuration ?? 800;
|
|
403
|
+
const clearance = options.approachClearance ?? 10;
|
|
404
|
+
const carrierDepth = resolveDepth(carrier);
|
|
405
|
+
const yaw = this._yawOf(holder);
|
|
406
|
+
const target = this._targetFor(holder, carrierDepth, yaw); // top-of-carrier after drop
|
|
407
|
+
const approach = this._targetFor(holder, carrierDepth + clearance, yaw);
|
|
408
|
+
this.set('target', approach);
|
|
399
409
|
await waitForTcpReached(this, timeoutMs);
|
|
400
|
-
|
|
401
|
-
this.set('target', placeTarget);
|
|
410
|
+
this.set('target', target);
|
|
402
411
|
await waitForTcpReached(this, timeoutMs);
|
|
403
|
-
|
|
412
|
+
holder.reparent?.(carrier, { animated: true, duration: reparentDuration });
|
|
404
413
|
this.set('gripper', { ...(this.state.gripper ?? {}), state: 0 });
|
|
405
414
|
await sleep(reparentDuration);
|
|
406
415
|
}
|
|
416
|
+
/**
|
|
417
|
+
* `pickAndPlace` is inherited from the `Mover` mixin default — runs
|
|
418
|
+
* `pick(carrier)` then `place(carrier, holder)` sequentially. The
|
|
419
|
+
* decomposition is safe: the carrier's world position only matters
|
|
420
|
+
* during pick (carrier-relative waypoints), and after pick the carrier
|
|
421
|
+
* is the TCP's child (so re-querying it would chase its own tail —
|
|
422
|
+
* which we don't, since place uses holder-relative waypoints only).
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* ```ts
|
|
426
|
+
* await robotArm.pickAndPlace(box, spotB)
|
|
427
|
+
* await robotArm.pnp(parcel, palletA, { approachClearance: 30 })
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
407
430
|
/** Short alias for `pickAndPlace`. Same arguments, same behavior. */
|
|
408
431
|
pnp(carrier, placeHolder, options) {
|
|
409
432
|
return this.pickAndPlace(carrier, placeHolder, options);
|
package/dist/robot-arm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"robot-arm.js","sourceRoot":"","sources":["../src/robot-arm.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Robot Arm — generalized articulated manipulator component.\n *\n * Designed to cover the visualization needs of robot arms WITHOUT a\n * specific URDF model. Configurable kinematic chain, link shape, joint\n * housing, gripper type — same component renders as a sleek cobot, a\n * heavy industrial 6-axis, a SCARA, or a minimal educational arm.\n *\n * State schema (all top-level properties optional except width/height):\n *\n * {\n * // structure\n * style?: 'industrial' | 'cobot' | 'scara' | 'minimal',\n * chainPreset?: '6-axis-industrial' | 'cobot-6-axis' | 'scara-4-axis' | 'pick-and-place-3-axis',\n * chain?: ChainElement[], // overrides preset\n * joints?: number[] | { [i]: number }, // current joint values\n *\n * // styling overrides\n * linkShape?, jointHousing?, linkRadius?, color?, accentColor?,\n *\n * // gripper\n * gripper?: GripperConfig,\n *\n * // IK target (TCP world position relative to component center, in\n * // 3D-z-up convention used by IK module)\n * target?: { x: number, y: number, z: number },\n *\n * // visualization\n * showReachSphere?: boolean\n * }\n */\n\nimport * as THREE from 'three'\nimport { Component, ComponentNature, Container, RealObject, sceneComponent } from '@hatiolab/things-scene'\nimport {\n CarrierHolder,\n Legendable,\n Placeable,\n type Alignment,\n type Heights,\n type LegendBinding,\n type PlacementArchetype\n} from '@operato/scene-base'\n\nimport { RobotArm3D } from './robot-arm-3d.js'\nimport { CHAIN_PRESETS, type ChainPresetName } from './robot-arm-styles.js'\nimport type { ChainElement } from './robot-arm-ik.js'\n\nexport type RobotArmStatus = 'idle' | 'moving' | 'gripping' | 'warn' | 'error'\n\nconst BODY_LEGEND = {\n idle: '#ccc',\n moving: '#afd0f1',\n gripping: '#cfe6c8',\n warn: '#ffba00',\n error: '#e9746b',\n default: '#ccc'\n}\n\nconst BORDER_LEGEND = {\n idle: '#888',\n moving: '#87b1db',\n gripping: '#7aa274',\n warn: '#d96f21',\n error: '#a73928',\n default: '#888'\n}\n\nconst LAMP_EMISSIVE_LEGEND = {\n idle: '#333333',\n moving: '#44aaff',\n gripping: '#33aa44',\n warn: '#ffaa00',\n error: '#ff3333',\n default: '#333333'\n}\n\nconst STATIC_PROPERTIES = [\n {\n type: 'select',\n label: 'style',\n name: 'style',\n property: {\n options: [\n { display: 'Industrial', value: 'industrial' },\n { display: 'Cobot', value: 'cobot' },\n { display: 'SCARA', value: 'scara' },\n { display: 'Minimal', value: 'minimal' }\n ]\n }\n },\n {\n type: 'select',\n label: 'chain-preset',\n name: 'chainPreset',\n property: {\n options: [\n { display: '6-Axis Industrial', value: '6-axis-industrial' },\n { display: 'Cobot 6-Axis', value: 'cobot-6-axis' },\n { display: 'SCARA 4-Axis', value: 'scara-4-axis' },\n { display: 'Pick & Place 3-Axis', value: 'pick-and-place-3-axis' }\n ]\n }\n },\n { type: 'number', label: 'link-radius', name: 'linkRadius' },\n {\n type: 'select',\n label: 'gripper-type',\n name: 'gripperType',\n property: {\n options: [\n { display: 'Parallel', value: 'parallel' },\n { display: 'Suction', value: 'suction' },\n { display: 'Magnetic', value: 'magnetic' },\n { display: 'Three-Finger', value: 'three-finger' },\n { display: 'None', value: 'none' }\n ]\n }\n },\n { type: 'checkbox', label: 'show-reach-sphere', name: 'showReachSphere' },\n {\n type: 'select',\n label: 'status',\n name: 'status',\n property: {\n options: [\n { display: 'Idle', value: 'idle' },\n { display: 'Moving', value: 'moving' },\n { display: 'Gripping', value: 'gripping' },\n { display: 'Warn', value: 'warn' },\n { display: 'Error', value: 'error' }\n ]\n }\n }\n]\n\n// CarrierHolder + Container: the arm needs Container's child-list machinery\n// (addComponent / reparent / events) AND CarrierHolder's attachPointFor\n// hook. CarrierHolder mixin alone only publishes the attach policy; it\n// doesn't add child management. RectPath(Shape) was wrong here — Shape is\n// a leaf so reparent silently failed. Container provides the missing piece.\nconst Base = CarrierHolder(Legendable(Placeable(Container))) as unknown as typeof Component\n\n@sceneComponent('robot-arm')\nexport default class RobotArm extends Base {\n static legends: Record<string, LegendBinding> = {\n bodyColor: { from: 'status', legend: BODY_LEGEND },\n borderColor: { from: 'status', legend: BORDER_LEGEND },\n lampEmissive: { from: 'status', legend: LAMP_EMISSIVE_LEGEND }\n }\n\n /**\n * Robot arms sit on the floor (or mount to a ceiling/wall — that's a\n * v2 feature). Default depth = operation - floor like other floor-\n * mounted equipment, so the chain reach scales with the configured\n * facility height.\n */\n static placement: PlacementArchetype = 'floor'\n static align: Alignment = 'bottom'\n static defaultDepth = (h: Heights) => h.operation - h.floor\n\n /**\n * Dynamic nature — appends one number property per joint in the active\n * chain. Each property uses the joint's range as `min`/`max` so the\n * property panel can render a constrained slider/spinner. The chain\n * preset can change at runtime, and `get nature()` is re-evaluated\n * whenever the property panel queries it, so the joint count stays in\n * sync with the active preset.\n *\n * For revolute joints the value is in radians; for prismatic, scene units.\n */\n get nature(): ComponentNature {\n const chain = this._activeChain\n // Joint values: revolute = degrees (range usually ±180), prismatic =\n // scene length units. CHAIN_PRESETS already encode revolute ranges in\n // degrees; the 3D side converts to radians at the math boundary.\n const jointProps = chain.map((c, i) => ({\n type: 'number',\n label: `joint-${i + 1}`,\n name: `joint${i}`,\n property: {\n min: c.range[0],\n max: c.range[1],\n step: c.type === 'revolute' ? 1 : 1\n }\n }))\n return {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [...STATIC_PROPERTIES, ...jointProps] as any,\n help: 'scene/component/robot-arm'\n }\n }\n\n /**\n * Resolve the active chain for property-panel introspection. Mirrors\n * the resolution in robot-arm-3d.ts (state.chain wins, else preset,\n * else default 6-axis-industrial). Kept simple — the 3D side does the\n * same logic with depth-based scaling, but for property labeling we\n * only need the structure (axis count + ranges), not absolute lengths.\n */\n private get _activeChain(): ChainElement[] {\n const state = this.state as any\n if (Array.isArray(state.chain) && state.chain.length > 0) return state.chain\n const presetName = (state.chainPreset ?? '6-axis-industrial') as ChainPresetName\n return CHAIN_PRESETS[presetName] ?? CHAIN_PRESETS['6-axis-industrial']\n }\n\n get anchors() {\n return []\n }\n\n /**\n * 2D — base rectangle + a stylized arm silhouette pointing toward the\n * top-right. Just enough to identify the component as a robot arm in\n * plan view; the real visual lives in 3D.\n */\n render(ctx: CanvasRenderingContext2D) {\n const { left = 0, top = 0, width = 100, height = 100 } = this.state\n const bodyFill = pickColor(this.state.fillStyle, (this.state as any).bodyColor, BODY_LEGEND.default)\n const borderColor = pickColor(this.state.strokeStyle, (this.state as any).borderColor, BORDER_LEGEND.default)\n const lineWidth = numOr(this.state.lineWidth, 1)\n\n ctx.beginPath()\n ctx.rect(left, top, width, height)\n ctx.fillStyle = bodyFill\n ctx.fill()\n ctx.strokeStyle = borderColor\n ctx.lineWidth = lineWidth\n ctx.stroke()\n\n // Stylized arm silhouette: base square at center → up → bent right.\n const cx = left + width / 2\n const cy = top + height / 2\n const r = Math.min(width, height) * 0.32\n ctx.save()\n ctx.strokeStyle = borderColor\n ctx.lineWidth = Math.max(lineWidth, Math.min(width, height) * 0.025)\n\n // Base pedestal\n ctx.fillStyle = borderColor\n ctx.fillRect(cx - r * 0.5, cy + r * 0.6, r, r * 0.3)\n // Upper arm\n ctx.beginPath()\n ctx.moveTo(cx, cy + r * 0.6)\n ctx.lineTo(cx, cy - r * 0.2)\n ctx.stroke()\n // Forearm\n ctx.beginPath()\n ctx.moveTo(cx, cy - r * 0.2)\n ctx.lineTo(cx + r * 0.7, cy - r * 0.7)\n ctx.stroke()\n // Joint dots\n ctx.fillStyle = borderColor as string\n ctx.beginPath()\n ctx.arc(cx, cy - r * 0.2, Math.max(2, r * 0.1), 0, Math.PI * 2)\n ctx.fill()\n ctx.beginPath()\n ctx.arc(cx + r * 0.7, cy - r * 0.7, Math.max(1.5, r * 0.08), 0, Math.PI * 2)\n ctx.fill()\n ctx.restore()\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n // Per-joint number properties (joint0 … jointN-1) are dynamic; treat\n // any key matching the pattern as a joint update.\n const hasJoint = Object.keys(after).some(k => /^joint\\d+$/.test(k))\n if (\n hasJoint ||\n 'style' in after ||\n 'chainPreset' in after ||\n 'chain' in after ||\n 'joints' in after ||\n 'linkShape' in after ||\n 'jointHousing' in after ||\n 'linkRadius' in after ||\n 'color' in after ||\n 'accentColor' in after ||\n 'fillStyle' in after ||\n 'strokeStyle' in after ||\n 'lineWidth' in after ||\n 'alpha' in after ||\n 'material3d' in after ||\n 'gripper' in after ||\n 'gripperType' in after ||\n 'target' in after ||\n 'showReachSphere' in after ||\n 'status' in after ||\n 'bodyColor' in after ||\n 'borderColor' in after\n ) {\n ;(this as any).clearCache?.('fillStyle')\n this.invalidate()\n }\n super.onchange(after, before)\n }\n\n buildRealObject(): RealObject | undefined {\n return new RobotArm3D(this as any)\n }\n\n /**\n * CarrierHolder hook — return the gripper TCP frame so any Carriable\n * child (parcel/box/pallet/...) mounts onto the moving end-effector.\n * IK rotation propagates to the carrier through Three.js scene-graph.\n *\n * Pose convention (real-world pick-and-place: gripper pointing toward\n * the work, carrier hanging *beyond* the gripper tip):\n *\n * - Frame: TCP (gripper working point — between finger tips for\n * jaws, contact face for suction/magnetic). Built by\n * `RobotArm3D._buildGripper`. TCP's +Z = gripper-forward direction\n * (away from the wrist).\n *\n * - Rotation: x:-π/2 — maps carrier's local +Y axis (\"up\" in the\n * carrier's authored frame) to TCP's -Z direction. With the gripper\n * pointing down (typical work pose), TCP +Z = world -Y (down), so\n * TCP -Z = world +Y (up). Result: carrier's \"up\" stays world-up\n * during transit, and the carrier's body extends from TCP origin\n * in TCP +Z direction (down in world) — i.e. hanging BELOW the\n * gripper, not buried inside it.\n *\n * - Position: z = +halfDepth — places the carrier's TOP face center\n * at the TCP origin (where the fingers grip). Carrier's local +Y\n * extent (top) = halfDepth, which after x:-π/2 rotation maps to\n * TCP -halfDepth Z. Shifting carrier center to TCP +halfDepth Z\n * puts that top point exactly at TCP origin. Carrier body then\n * extends through TCP +Z, ending at TCP +depth (bottom face).\n *\n * Earlier (x:+π/2, z:-halfDepth) inverted the carrier's body direction\n * — body extended back into the wrist, leaving the box visually inside\n * the finger area. The current convention pushes the body OUT past the\n * fingertips, where a real gripper would hold it.\n */\n attachPointFor(carrier: Component) {\n const ro = (this as any)._realObject as RobotArm3D | undefined\n const frame = ro?.getGripperFrame?.()\n if (!frame) return undefined\n const halfDepth = resolveDepth(carrier) / 2\n return {\n attach: frame,\n localPosition: { x: 0, y: 0, z: halfDepth },\n localRotation: { x: -Math.PI / 2, y: 0, z: 0 }\n }\n }\n\n /**\n * High-level pick-and-place automation with vertical-entry waypoints.\n *\n * Movement sequence:\n *\n * 1. TCP → APPROACH above pick (carrier's xy, +clearance in world Y)\n * 2. TCP → pick (descend straight down to carrier's top face)\n * 3. close gripper + reparent(carrier → this)\n * 4. TCP → APPROACH above place (carries the carrier up & over —\n * the IK path naturally lifts then descends to the new approach\n * pose since the approach is higher than pick)\n * 5. TCP → place (descend straight down to drop point)\n * 6. open gripper + reparent(carrier → placeHolder)\n *\n * The point of the approach waypoints is to make the FINAL leg of\n * each pick/place be a clean vertical descent — so the gripper enters\n * the carrier from straight above, not from a sideways sweep that\n * could clip the carrier or grab it at a wrong angle.\n *\n * Pose resolution:\n * - Pick: TCP lands on the CARRIER'S TOP FACE (carrier.world.y +\n * carrier.depth/2). After grip, attachPointFor's\n * `localPosition.z = +halfDepth` keeps the carrier's top at TCP\n * origin during transit — exact, no offset drift.\n * - Place: TCP lands at where the carrier's top WILL BE after the\n * drop, so the carrier lands with its bottom on the placeHolder's\n * attach surface (top-of-pad for Spot, etc.). Computed as\n * `placeHolder.attachFrame.world.y + carrier.depth`.\n *\n * @param options.approachClearance Vertical offset (world units)\n * between the approach waypoint and the pick/place target. Small\n * (default 10) — just enough to make the final leg a clean\n * straight-down vertical descent. Bump it for tall carriers or\n * crowded scenes.\n * @param options.timeoutMs Per-segment IK timeout (default 15000ms).\n *\n * @example\n * ```ts\n * await robotArm.pickAndPlace(box, spotB)\n * await robotArm.pnp(parcel, palletA, { approachClearance: 30 })\n * ```\n */\n async pickAndPlace(\n carrier: Component,\n placeHolder: Component,\n options: { timeoutMs?: number; reparentDuration?: number; approachClearance?: number } = {}\n ): Promise<void> {\n const timeoutMs = options.timeoutMs ?? 15000\n const reparentDuration = options.reparentDuration ?? 800\n // Read carrier height via _realObject.effectiveDepth — `state.depth`\n // is often not explicitly set (carriers like Box rely on\n // `static defaultDepth`), and reading state alone returns 0, which\n // collapses every Y offset and drives the gripper into the carrier's\n // volumetric center instead of its top face.\n const carrierDepth = resolveDepth(carrier)\n const clearance = options.approachClearance ?? 10\n\n // Pre-compute all waypoints once. Recomputing mid-sequence would\n // pick up the carrier's NEW world position once it's parented to\n // the gripper (= TCP itself), causing a chase-your-tail loop.\n //\n // Each waypoint includes the target's world yaw so the IK can spin\n // joint 5 (tool roll) to align the gripper's \"side\" with the\n // carrier's — without it, reparent at pick instantly snaps the\n // carrier to the gripper's axis, visibly twisting it 0° → up to\n // 360° in one frame. Same problem inverted at place.\n const halfDepth = carrierDepth / 2\n const pickYaw = this._yawOf(carrier)\n const placeYaw = this._yawOf(placeHolder)\n const pickTarget = this._targetFor(carrier, halfDepth, pickYaw)\n const pickApproach = this._targetFor(carrier, halfDepth + clearance, pickYaw)\n const placeTarget = this._targetFor(placeHolder, carrierDepth, placeYaw) // top-of-carrier after drop\n const placeApproach = this._targetFor(placeHolder, carrierDepth + clearance, placeYaw)\n\n // 1. Approach above pick.\n this.set('target', pickApproach)\n await waitForTcpReached(this, timeoutMs)\n\n // 2. Descend straight down to the carrier's top face.\n this.set('target', pickTarget)\n await waitForTcpReached(this, timeoutMs)\n\n // 3. Grip + reparent.\n ;(this as any).reparent?.(carrier, { animated: true, duration: reparentDuration })\n this.set('gripper', { ...((this.state as any).gripper ?? {}), state: 1 })\n await sleep(reparentDuration)\n\n // 4. Move to approach above place (IK path lifts up & travels over).\n this.set('target', placeApproach)\n await waitForTcpReached(this, timeoutMs)\n\n // 5. Descend straight down to drop position.\n this.set('target', placeTarget)\n await waitForTcpReached(this, timeoutMs)\n\n // 6. Release + reparent.\n ;(placeHolder as any).reparent?.(carrier, { animated: true, duration: reparentDuration })\n this.set('gripper', { ...((this.state as any).gripper ?? {}), state: 0 })\n await sleep(reparentDuration)\n }\n\n /** Short alias for `pickAndPlace`. Same arguments, same behavior. */\n pnp(\n carrier: Component,\n placeHolder: Component,\n options?: { timeoutMs?: number; reparentDuration?: number; approachClearance?: number }\n ): Promise<void> {\n return this.pickAndPlace(carrier, placeHolder, options)\n }\n\n /**\n * Resolve a TCP position in this arm's chain-local frame.\n *\n * For a CarrierHolder (has `attachPointFor`), uses the holder's own\n * attach frame as the base — that's the canonical \"where carriers\n * sit on me\" point (top of Spot's pad, gripper TCP for another arm,\n * etc.). For a plain carrier, uses its world center.\n *\n * `worldYOffset` is added to the resolved world Y before projecting\n * back to chain-local — used by pickAndPlace to lift the TCP above\n * the target (approach waypoints) and to land it on the carrier's\n * top face rather than its volumetric center.\n */\n private _targetFor(\n component: Component,\n worldYOffset = 0,\n yaw?: number\n ): { x: number; y: number; z: number; yaw?: number } {\n const ro3d = (this as any)._realObject as RobotArm3D | undefined\n\n let baseWp: THREE.Vector3 | undefined\n // Prefer holder's attach frame when available.\n const attachPointFor = (component as any).attachPointFor\n if (typeof attachPointFor === 'function') {\n const point = attachPointFor.call(component, this)\n if (point?.attach) {\n point.attach.updateWorldMatrix?.(true, false)\n baseWp = point.attach.getWorldPosition?.(new THREE.Vector3())\n }\n }\n if (!baseWp) {\n const obj = (component as any)._realObject?.object3d\n if (obj) {\n obj.updateWorldMatrix(true, false)\n baseWp = obj.getWorldPosition(new THREE.Vector3())\n }\n }\n if (!ro3d || !baseWp) {\n // Final fallback: 2D bounds center — only before 3D builds.\n const c = component.center\n return { x: c.x, y: worldYOffset, z: c.y, yaw }\n }\n const local = ro3d.worldToChainLocal(baseWp.x, baseWp.y + worldYOffset, baseWp.z)\n return { x: local.x, y: local.y, z: local.z, yaw }\n }\n\n /**\n * Extract a component's world yaw (rotation around world +Y) from its\n * 3D object's world matrix. Returns 0 if the object isn't built yet.\n * Used by `pickAndPlace` so the gripper can match the carrier's /\n * placeHolder's current orientation — preventing a yaw snap at the\n * moment of reparent.\n */\n private _yawOf(component: Component): number {\n const obj = (component as any)._realObject?.object3d\n if (!obj) return 0\n obj.updateWorldMatrix(true, false)\n const q = new THREE.Quaternion()\n obj.getWorldQuaternion(q)\n const e = new THREE.Euler().setFromQuaternion(q, 'YXZ')\n return e.y\n }\n}\n\n/**\n * Resolve when the robot arm fires `tcp-reached`, reject on timeout.\n * The 3D side fires this event on smoothing completion (last joint\n * value within threshold of its target).\n */\nfunction waitForTcpReached(component: Component, timeoutMs: number): Promise<void> {\n return new Promise((resolve, reject) => {\n let timer: any\n const onReached = () => {\n clearTimeout(timer)\n ;(component as any).off?.('tcp-reached', onReached)\n resolve()\n }\n timer = setTimeout(() => {\n ;(component as any).off?.('tcp-reached', onReached)\n reject(new Error('TCP reach timeout'))\n }, timeoutMs)\n ;(component as any).on?.('tcp-reached', onReached)\n })\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n\nfunction numOr(v: unknown, dflt: number): number {\n return typeof v === 'number' && Number.isFinite(v) ? v : dflt\n}\n\n/**\n * Resolve a component's 3D height. things-scene v10 carriers (Box, Pallet,\n * etc.) typically declare `static defaultDepth` rather than setting\n * `state.depth`, so reading state alone returns 0 — wrong for a\n * default-sized box. The framework resolves the actual value into\n * `_realObject.effectiveDepth`. Falls back to `state.depth` for\n * components built before their RealObject exists.\n */\nfunction resolveDepth(c: Component): number {\n const eff = (c as any)?._realObject?.effectiveDepth\n if (typeof eff === 'number' && Number.isFinite(eff)) return eff\n return numOr((c as any)?.state?.depth, 0)\n}\n\nfunction pickColor(...candidates: unknown[]): string {\n for (const c of candidates) {\n if (typeof c === 'string' && c && c !== 'transparent') return c\n }\n return '#888'\n}\n"]}
|
|
1
|
+
{"version":3,"file":"robot-arm.js","sourceRoot":"","sources":["../src/robot-arm.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Robot Arm — generalized articulated manipulator component.\n *\n * Designed to cover the visualization needs of robot arms WITHOUT a\n * specific URDF model. Configurable kinematic chain, link shape, joint\n * housing, gripper type — same component renders as a sleek cobot, a\n * heavy industrial 6-axis, a SCARA, or a minimal educational arm.\n *\n * State schema (all top-level properties optional except width/height):\n *\n * {\n * // structure\n * style?: 'industrial' | 'cobot' | 'scara' | 'minimal',\n * chainPreset?: '6-axis-industrial' | 'cobot-6-axis' | 'scara-4-axis' | 'pick-and-place-3-axis',\n * chain?: ChainElement[], // overrides preset\n * joints?: number[] | { [i]: number }, // current joint values\n *\n * // styling overrides\n * linkShape?, jointHousing?, linkRadius?, color?, accentColor?,\n *\n * // gripper\n * gripper?: GripperConfig,\n *\n * // IK target (TCP world position relative to component center, in\n * // 3D-z-up convention used by IK module)\n * target?: { x: number, y: number, z: number },\n *\n * // visualization\n * showReachSphere?: boolean\n * }\n */\n\nimport * as THREE from 'three'\nimport { Component, ComponentNature, ContainerAbstract, RealObject, sceneComponent } from '@hatiolab/things-scene'\nimport {\n CarrierHolder,\n Legendable,\n Mover,\n Placeable,\n type Alignment,\n type Heights,\n type LegendBinding,\n type MoveOptions,\n type PlacementArchetype\n} from '@operato/scene-base'\n\nimport { RobotArm3D } from './robot-arm-3d.js'\nimport { CHAIN_PRESETS, type ChainPresetName } from './robot-arm-styles.js'\nimport type { ChainElement } from './robot-arm-ik.js'\n\nexport type RobotArmStatus = 'idle' | 'moving' | 'gripping' | 'warn' | 'error'\n\nconst BODY_LEGEND = {\n idle: '#ccc',\n moving: '#afd0f1',\n gripping: '#cfe6c8',\n warn: '#ffba00',\n error: '#e9746b',\n default: '#ccc'\n}\n\nconst BORDER_LEGEND = {\n idle: '#888',\n moving: '#87b1db',\n gripping: '#7aa274',\n warn: '#d96f21',\n error: '#a73928',\n default: '#888'\n}\n\nconst LAMP_EMISSIVE_LEGEND = {\n idle: '#333333',\n moving: '#44aaff',\n gripping: '#33aa44',\n warn: '#ffaa00',\n error: '#ff3333',\n default: '#333333'\n}\n\nconst STATIC_PROPERTIES = [\n {\n type: 'select',\n label: 'style',\n name: 'style',\n property: {\n options: [\n { display: 'Industrial', value: 'industrial' },\n { display: 'Cobot', value: 'cobot' },\n { display: 'SCARA', value: 'scara' },\n { display: 'Minimal', value: 'minimal' }\n ]\n }\n },\n {\n type: 'select',\n label: 'chain-preset',\n name: 'chainPreset',\n property: {\n options: [\n { display: '6-Axis Industrial', value: '6-axis-industrial' },\n { display: 'Cobot 6-Axis', value: 'cobot-6-axis' },\n { display: 'SCARA 4-Axis', value: 'scara-4-axis' },\n { display: 'Pick & Place 3-Axis', value: 'pick-and-place-3-axis' }\n ]\n }\n },\n { type: 'number', label: 'link-radius', name: 'linkRadius' },\n {\n type: 'select',\n label: 'gripper-type',\n name: 'gripperType',\n property: {\n options: [\n { display: 'Parallel', value: 'parallel' },\n { display: 'Suction', value: 'suction' },\n { display: 'Magnetic', value: 'magnetic' },\n { display: 'Three-Finger', value: 'three-finger' },\n { display: 'None', value: 'none' }\n ]\n }\n },\n { type: 'checkbox', label: 'show-reach-sphere', name: 'showReachSphere' },\n {\n type: 'select',\n label: 'status',\n name: 'status',\n property: {\n options: [\n { display: 'Idle', value: 'idle' },\n { display: 'Moving', value: 'moving' },\n { display: 'Gripping', value: 'gripping' },\n { display: 'Warn', value: 'warn' },\n { display: 'Error', value: 'error' }\n ]\n }\n }\n]\n\n// CarrierHolder + ContainerAbstract: the arm needs the container's child-list\n// machinery (addComponent / reparent / events) AND CarrierHolder's\n// attachPointFor hook. CarrierHolder mixin alone only publishes the attach\n// policy; it doesn't add child management. RectPath(Shape) was wrong here —\n// Shape is a leaf so reparent silently failed. ContainerAbstract provides\n// the missing piece.\n//\n// `ContainerAbstract` (not `Container`) — Container = MixinHTMLElement(ContainerAbstract),\n// which forces `isHTMLElement(): true` and trips the 3D pipeline's\n// addObject DOM-skip gate. Robot arm exists purely in the 3D scene graph\n// (URDF/IK joints, no DOM overlay), so the bare logical container is correct.\n//\n// Mover wraps the chain to publish pick/place/pickAndPlace primitives. It\n// must sit OUTSIDE CarrierHolder because Mover's defaults call this.reparent,\n// which CarrierHolder provides (overrides the base ContainerAbstract\n// version with the attach-frame-aware variant).\n//\n// The instance type cast surfaces Mover's API on `this` so subclass\n// `override` keywords compile and `this.pickAndPlace(...)` resolves —\n// without it, the `as unknown as typeof Component` cast erases all\n// mixin contributions to the static side.\nconst Base = Mover(CarrierHolder(Legendable(Placeable(ContainerAbstract)))) as unknown as typeof Component & {\n new (...args: any[]): Component & {\n isMover: boolean\n pick(carrier: Component, options?: MoveOptions): Promise<void>\n place(carrier: Component, holder: Component, options?: MoveOptions): Promise<void>\n pickAndPlace(carrier: Component, holder: Component, options?: MoveOptions): Promise<void>\n }\n}\n\n@sceneComponent('robot-arm')\nexport default class RobotArm extends Base {\n static legends: Record<string, LegendBinding> = {\n bodyColor: { from: 'status', legend: BODY_LEGEND },\n borderColor: { from: 'status', legend: BORDER_LEGEND },\n lampEmissive: { from: 'status', legend: LAMP_EMISSIVE_LEGEND }\n }\n\n /**\n * Robot arms sit on the floor (or mount to a ceiling/wall — that's a\n * v2 feature). Default depth = operation - floor like other floor-\n * mounted equipment, so the chain reach scales with the configured\n * facility height.\n */\n static placement: PlacementArchetype = 'floor'\n static align: Alignment = 'bottom'\n static defaultDepth = (h: Heights) => h.operation - h.floor\n\n /**\n * Dynamic nature — appends one number property per joint in the active\n * chain. Each property uses the joint's range as `min`/`max` so the\n * property panel can render a constrained slider/spinner. The chain\n * preset can change at runtime, and `get nature()` is re-evaluated\n * whenever the property panel queries it, so the joint count stays in\n * sync with the active preset.\n *\n * For revolute joints the value is in radians; for prismatic, scene units.\n */\n get nature(): ComponentNature {\n const chain = this._activeChain\n // Joint values: revolute = degrees (range usually ±180), prismatic =\n // scene length units. CHAIN_PRESETS already encode revolute ranges in\n // degrees; the 3D side converts to radians at the math boundary.\n const jointProps = chain.map((c, i) => ({\n type: 'number',\n label: `joint-${i + 1}`,\n name: `joint${i}`,\n property: {\n min: c.range[0],\n max: c.range[1],\n step: c.type === 'revolute' ? 1 : 1\n }\n }))\n return {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [...STATIC_PROPERTIES, ...jointProps] as any,\n help: 'scene/component/robot-arm'\n }\n }\n\n /**\n * Resolve the active chain for property-panel introspection. Mirrors\n * the resolution in robot-arm-3d.ts (state.chain wins, else preset,\n * else default 6-axis-industrial). Kept simple — the 3D side does the\n * same logic with depth-based scaling, but for property labeling we\n * only need the structure (axis count + ranges), not absolute lengths.\n */\n private get _activeChain(): ChainElement[] {\n const state = this.state as any\n if (Array.isArray(state.chain) && state.chain.length > 0) return state.chain\n const presetName = (state.chainPreset ?? '6-axis-industrial') as ChainPresetName\n return CHAIN_PRESETS[presetName] ?? CHAIN_PRESETS['6-axis-industrial']\n }\n\n get anchors() {\n return []\n }\n\n /**\n * 2D — base rectangle + a stylized arm silhouette pointing toward the\n * top-right. Just enough to identify the component as a robot arm in\n * plan view; the real visual lives in 3D.\n */\n render(ctx: CanvasRenderingContext2D) {\n const { left = 0, top = 0, width = 100, height = 100 } = this.state\n const bodyFill = pickColor(this.state.fillStyle, (this.state as any).bodyColor, BODY_LEGEND.default)\n const borderColor = pickColor(this.state.strokeStyle, (this.state as any).borderColor, BORDER_LEGEND.default)\n const lineWidth = numOr(this.state.lineWidth, 1)\n\n ctx.beginPath()\n ctx.rect(left, top, width, height)\n ctx.fillStyle = bodyFill\n ctx.fill()\n ctx.strokeStyle = borderColor\n ctx.lineWidth = lineWidth\n ctx.stroke()\n\n // Stylized arm silhouette: base square at center → up → bent right.\n const cx = left + width / 2\n const cy = top + height / 2\n const r = Math.min(width, height) * 0.32\n ctx.save()\n ctx.strokeStyle = borderColor\n ctx.lineWidth = Math.max(lineWidth, Math.min(width, height) * 0.025)\n\n // Base pedestal\n ctx.fillStyle = borderColor\n ctx.fillRect(cx - r * 0.5, cy + r * 0.6, r, r * 0.3)\n // Upper arm\n ctx.beginPath()\n ctx.moveTo(cx, cy + r * 0.6)\n ctx.lineTo(cx, cy - r * 0.2)\n ctx.stroke()\n // Forearm\n ctx.beginPath()\n ctx.moveTo(cx, cy - r * 0.2)\n ctx.lineTo(cx + r * 0.7, cy - r * 0.7)\n ctx.stroke()\n // Joint dots\n ctx.fillStyle = borderColor as string\n ctx.beginPath()\n ctx.arc(cx, cy - r * 0.2, Math.max(2, r * 0.1), 0, Math.PI * 2)\n ctx.fill()\n ctx.beginPath()\n ctx.arc(cx + r * 0.7, cy - r * 0.7, Math.max(1.5, r * 0.08), 0, Math.PI * 2)\n ctx.fill()\n ctx.restore()\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n // Per-joint number properties (joint0 … jointN-1) are dynamic; treat\n // any key matching the pattern as a joint update.\n const hasJoint = Object.keys(after).some(k => /^joint\\d+$/.test(k))\n if (\n hasJoint ||\n 'style' in after ||\n 'chainPreset' in after ||\n 'chain' in after ||\n 'joints' in after ||\n 'linkShape' in after ||\n 'jointHousing' in after ||\n 'linkRadius' in after ||\n 'color' in after ||\n 'accentColor' in after ||\n 'fillStyle' in after ||\n 'strokeStyle' in after ||\n 'lineWidth' in after ||\n 'alpha' in after ||\n 'material3d' in after ||\n 'gripper' in after ||\n 'gripperType' in after ||\n 'target' in after ||\n 'showReachSphere' in after ||\n 'status' in after ||\n 'bodyColor' in after ||\n 'borderColor' in after\n ) {\n ;(this as any).clearCache?.('fillStyle')\n this.invalidate()\n }\n super.onchange(after, before)\n }\n\n buildRealObject(): RealObject | undefined {\n return new RobotArm3D(this as any)\n }\n\n /**\n * CarrierHolder hook — return the gripper TCP frame so any Carriable\n * child (parcel/box/pallet/...) mounts onto the moving end-effector.\n * IK rotation propagates to the carrier through Three.js scene-graph.\n *\n * Pose convention (real-world pick-and-place: gripper pointing toward\n * the work, carrier hanging *beyond* the gripper tip):\n *\n * - Frame: TCP (gripper working point — between finger tips for\n * jaws, contact face for suction/magnetic). Built by\n * `RobotArm3D._buildGripper`. TCP's +Z = gripper-forward direction\n * (away from the wrist).\n *\n * - Rotation: x:-π/2 — maps carrier's local +Y axis (\"up\" in the\n * carrier's authored frame) to TCP's -Z direction. With the gripper\n * pointing down (typical work pose), TCP +Z = world -Y (down), so\n * TCP -Z = world +Y (up). Result: carrier's \"up\" stays world-up\n * during transit, and the carrier's body extends from TCP origin\n * in TCP +Z direction (down in world) — i.e. hanging BELOW the\n * gripper, not buried inside it.\n *\n * - Position: z = +halfDepth — places the carrier's TOP face center\n * at the TCP origin (where the fingers grip). Carrier's local +Y\n * extent (top) = halfDepth, which after x:-π/2 rotation maps to\n * TCP -halfDepth Z. Shifting carrier center to TCP +halfDepth Z\n * puts that top point exactly at TCP origin. Carrier body then\n * extends through TCP +Z, ending at TCP +depth (bottom face).\n *\n * Earlier (x:+π/2, z:-halfDepth) inverted the carrier's body direction\n * — body extended back into the wrist, leaving the box visually inside\n * the finger area. The current convention pushes the body OUT past the\n * fingertips, where a real gripper would hold it.\n */\n attachPointFor(carrier: Component) {\n const ro = (this as any)._realObject as RobotArm3D | undefined\n const frame = ro?.getGripperFrame?.()\n if (!frame) return undefined\n const halfDepth = resolveDepth(carrier) / 2\n return {\n attach: frame,\n localPosition: { x: 0, y: 0, z: halfDepth },\n localRotation: { x: -Math.PI / 2, y: 0, z: 0 }\n }\n }\n\n /**\n * Pick: TCP descends vertically onto the carrier's top face, gripper\n * closes, carrier becomes our child.\n *\n * 1. TCP → APPROACH above pick (carrier's xy, +clearance in world Y)\n * 2. TCP → pick (descend straight down to carrier's top face)\n * 3. close gripper + reparent(carrier → this)\n *\n * The approach waypoint exists so the FINAL leg is a clean vertical\n * descent — the gripper enters the carrier from straight above, not a\n * sideways sweep that could clip or grab at a wrong angle.\n *\n * Pose resolution: TCP lands on the CARRIER'S TOP FACE (carrier.world.y +\n * carrier.depth/2). After grip, `attachPointFor`'s `localPosition.z =\n * +halfDepth` keeps the carrier's top at TCP origin during transit —\n * exact, no offset drift.\n *\n * Each waypoint includes the carrier's world yaw so IK can spin joint 5\n * (tool roll) to align the gripper's \"side\" with the carrier's. Without\n * it, reparent at pick instantly snaps the carrier to the gripper's\n * axis, visibly twisting it 0° → up to 360° in one frame.\n *\n * @param options.approachClearance Vertical offset (world units)\n * between approach and pick targets. Default 10.\n * @param options.timeoutMs Per-segment IK timeout (default 15000ms).\n * @param options.reparentDuration Animation duration for reparent (default 800ms).\n */\n override async pick(carrier: Component, options: MoveOptions = {}): Promise<void> {\n const timeoutMs = (options.timeoutMs as number | undefined) ?? 15000\n const reparentDuration = (options.reparentDuration as number | undefined) ?? 800\n const clearance = (options.approachClearance as number | undefined) ?? 10\n // Read carrier height via _realObject.effectiveDepth — `state.depth`\n // is often not explicitly set (carriers like Box rely on\n // `static defaultDepth`), and reading state alone returns 0, which\n // collapses every Y offset and drives the gripper into the carrier's\n // volumetric center instead of its top face.\n const carrierDepth = resolveDepth(carrier)\n const halfDepth = carrierDepth / 2\n const yaw = this._yawOf(carrier)\n const target = this._targetFor(carrier, halfDepth, yaw)\n const approach = this._targetFor(carrier, halfDepth + clearance, yaw)\n\n this.set('target', approach)\n await waitForTcpReached(this, timeoutMs)\n\n this.set('target', target)\n await waitForTcpReached(this, timeoutMs)\n\n ;(this as any).reparent?.(carrier, { animated: true, duration: reparentDuration })\n this.set('gripper', { ...((this.state as any).gripper ?? {}), state: 1 })\n await sleep(reparentDuration)\n }\n\n /**\n * Place: TCP descends vertically over the holder, gripper opens,\n * carrier becomes the holder's child.\n *\n * 1. TCP → APPROACH above place (carrier's xy, +clearance)\n * 2. TCP → place (descend straight down to drop point)\n * 3. open gripper + reparent(carrier → holder)\n *\n * Pose resolution: TCP lands at where the carrier's top WILL BE after\n * the drop, so the carrier lands with its bottom on the holder's attach\n * surface. Computed as `holder.attachFrame.world.y + carrier.depth` (so\n * yOffset = carrierDepth, not halfDepth like pick).\n *\n * @see pick — same option semantics.\n */\n override async place(carrier: Component, holder: Component, options: MoveOptions = {}): Promise<void> {\n const timeoutMs = (options.timeoutMs as number | undefined) ?? 15000\n const reparentDuration = (options.reparentDuration as number | undefined) ?? 800\n const clearance = (options.approachClearance as number | undefined) ?? 10\n const carrierDepth = resolveDepth(carrier)\n const yaw = this._yawOf(holder)\n const target = this._targetFor(holder, carrierDepth, yaw) // top-of-carrier after drop\n const approach = this._targetFor(holder, carrierDepth + clearance, yaw)\n\n this.set('target', approach)\n await waitForTcpReached(this, timeoutMs)\n\n this.set('target', target)\n await waitForTcpReached(this, timeoutMs)\n\n ;(holder as any).reparent?.(carrier, { animated: true, duration: reparentDuration })\n this.set('gripper', { ...((this.state as any).gripper ?? {}), state: 0 })\n await sleep(reparentDuration)\n }\n\n /**\n * `pickAndPlace` is inherited from the `Mover` mixin default — runs\n * `pick(carrier)` then `place(carrier, holder)` sequentially. The\n * decomposition is safe: the carrier's world position only matters\n * during pick (carrier-relative waypoints), and after pick the carrier\n * is the TCP's child (so re-querying it would chase its own tail —\n * which we don't, since place uses holder-relative waypoints only).\n *\n * @example\n * ```ts\n * await robotArm.pickAndPlace(box, spotB)\n * await robotArm.pnp(parcel, palletA, { approachClearance: 30 })\n * ```\n */\n /** Short alias for `pickAndPlace`. Same arguments, same behavior. */\n pnp(carrier: Component, placeHolder: Component, options?: MoveOptions): Promise<void> {\n return this.pickAndPlace(carrier, placeHolder, options)\n }\n\n /**\n * Resolve a TCP position in this arm's chain-local frame.\n *\n * For a CarrierHolder (has `attachPointFor`), uses the holder's own\n * attach frame as the base — that's the canonical \"where carriers\n * sit on me\" point (top of Spot's pad, gripper TCP for another arm,\n * etc.). For a plain carrier, uses its world center.\n *\n * `worldYOffset` is added to the resolved world Y before projecting\n * back to chain-local — used by pickAndPlace to lift the TCP above\n * the target (approach waypoints) and to land it on the carrier's\n * top face rather than its volumetric center.\n */\n private _targetFor(\n component: Component,\n worldYOffset = 0,\n yaw?: number\n ): { x: number; y: number; z: number; yaw?: number } {\n const ro3d = (this as any)._realObject as RobotArm3D | undefined\n\n let baseWp: THREE.Vector3 | undefined\n // Prefer holder's attach frame when available.\n const attachPointFor = (component as any).attachPointFor\n if (typeof attachPointFor === 'function') {\n const point = attachPointFor.call(component, this)\n if (point?.attach) {\n point.attach.updateWorldMatrix?.(true, false)\n baseWp = point.attach.getWorldPosition?.(new THREE.Vector3())\n }\n }\n if (!baseWp) {\n const obj = (component as any)._realObject?.object3d\n if (obj) {\n obj.updateWorldMatrix(true, false)\n baseWp = obj.getWorldPosition(new THREE.Vector3())\n }\n }\n if (!ro3d || !baseWp) {\n // Final fallback: 2D bounds center — only before 3D builds.\n const c = component.center\n return { x: c.x, y: worldYOffset, z: c.y, yaw }\n }\n const local = ro3d.worldToChainLocal(baseWp.x, baseWp.y + worldYOffset, baseWp.z)\n return { x: local.x, y: local.y, z: local.z, yaw }\n }\n\n /**\n * Extract a component's world yaw (rotation around world +Y) from its\n * 3D object's world matrix. Returns 0 if the object isn't built yet.\n * Used by `pickAndPlace` so the gripper can match the carrier's /\n * placeHolder's current orientation — preventing a yaw snap at the\n * moment of reparent.\n */\n private _yawOf(component: Component): number {\n const obj = (component as any)._realObject?.object3d\n if (!obj) return 0\n obj.updateWorldMatrix(true, false)\n const q = new THREE.Quaternion()\n obj.getWorldQuaternion(q)\n const e = new THREE.Euler().setFromQuaternion(q, 'YXZ')\n return e.y\n }\n}\n\n/**\n * Resolve when the robot arm fires `tcp-reached`, reject on timeout.\n * The 3D side fires this event on smoothing completion (last joint\n * value within threshold of its target).\n */\nfunction waitForTcpReached(component: Component, timeoutMs: number): Promise<void> {\n return new Promise((resolve, reject) => {\n let timer: any\n const onReached = () => {\n clearTimeout(timer)\n ;(component as any).off?.('tcp-reached', onReached)\n resolve()\n }\n timer = setTimeout(() => {\n ;(component as any).off?.('tcp-reached', onReached)\n reject(new Error('TCP reach timeout'))\n }, timeoutMs)\n ;(component as any).on?.('tcp-reached', onReached)\n })\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n\nfunction numOr(v: unknown, dflt: number): number {\n return typeof v === 'number' && Number.isFinite(v) ? v : dflt\n}\n\n/**\n * Resolve a component's 3D height. things-scene v10 carriers (Box, Pallet,\n * etc.) typically declare `static defaultDepth` rather than setting\n * `state.depth`, so reading state alone returns 0 — wrong for a\n * default-sized box. The framework resolves the actual value into\n * `_realObject.effectiveDepth`. Falls back to `state.depth` for\n * components built before their RealObject exists.\n */\nfunction resolveDepth(c: Component): number {\n const eff = (c as any)?._realObject?.effectiveDepth\n if (typeof eff === 'number' && Number.isFinite(eff)) return eff\n return numOr((c as any)?.state?.depth, 0)\n}\n\nfunction pickColor(...candidates: unknown[]): string {\n for (const c of candidates) {\n if (typeof c === 'string' && c && c !== 'transparent') return c\n }\n return '#888'\n}\n"]}
|
|
@@ -33,6 +33,15 @@ declare const _default: ({
|
|
|
33
33
|
left: number;
|
|
34
34
|
width: number;
|
|
35
35
|
height: number;
|
|
36
|
+
depth: number;
|
|
37
|
+
rotation: number;
|
|
38
|
+
linkRadius: number;
|
|
39
|
+
joint0: number;
|
|
40
|
+
joint1: number;
|
|
41
|
+
joint2: number;
|
|
42
|
+
joint3: number;
|
|
43
|
+
joint4: number;
|
|
44
|
+
joint5: number;
|
|
36
45
|
style: string;
|
|
37
46
|
chainPreset: string;
|
|
38
47
|
gripperType: string;
|
|
@@ -9,6 +9,15 @@ declare const _default: {
|
|
|
9
9
|
left: number;
|
|
10
10
|
width: number;
|
|
11
11
|
height: number;
|
|
12
|
+
depth: number;
|
|
13
|
+
rotation: number;
|
|
14
|
+
linkRadius: number;
|
|
15
|
+
joint0: number;
|
|
16
|
+
joint1: number;
|
|
17
|
+
joint2: number;
|
|
18
|
+
joint3: number;
|
|
19
|
+
joint4: number;
|
|
20
|
+
joint5: number;
|
|
12
21
|
style: string;
|
|
13
22
|
chainPreset: string;
|
|
14
23
|
gripperType: string;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
// icon is drawn.
|
|
3
|
-
const icon = new URL('../../icons/tact-timer.png', import.meta.url).href;
|
|
1
|
+
const icon = new URL('../../icons/robot-arm.png', import.meta.url).href;
|
|
4
2
|
export default {
|
|
5
3
|
type: 'robot-arm',
|
|
6
4
|
description: 'articulated robot arm — configurable kinematic chain with style/gripper options and IK',
|
|
@@ -10,8 +8,17 @@ export default {
|
|
|
10
8
|
type: 'robot-arm',
|
|
11
9
|
top: 200,
|
|
12
10
|
left: 200,
|
|
13
|
-
width:
|
|
14
|
-
height:
|
|
11
|
+
width: 5,
|
|
12
|
+
height: 5,
|
|
13
|
+
depth: 80,
|
|
14
|
+
rotation: 0,
|
|
15
|
+
linkRadius: 2,
|
|
16
|
+
joint0: 106,
|
|
17
|
+
joint1: 48,
|
|
18
|
+
joint2: 31,
|
|
19
|
+
joint3: -26,
|
|
20
|
+
joint4: 48,
|
|
21
|
+
joint5: 29,
|
|
15
22
|
style: 'industrial',
|
|
16
23
|
chainPreset: '6-axis-industrial',
|
|
17
24
|
gripperType: 'parallel',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"robot-arm.js","sourceRoot":"","sources":["../../src/templates/robot-arm.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"robot-arm.js","sourceRoot":"","sources":["../../src/templates/robot-arm.ts"],"names":[],"mappings":"AAAA,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,2BAA2B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAA;AAEvE,eAAe;IACb,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE,wFAAwF;IACrG,KAAK,EAAE,eAAe,CAAC,sIAAsI;IAC7J,IAAI;IACJ,KAAK,EAAE;QACL,IAAI,EAAE,WAAW;QACjB,GAAG,EAAE,GAAG;QACR,IAAI,EAAE,GAAG;QACT,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,CAAC;QACT,KAAK,EAAE,EAAE;QACT,QAAQ,EAAE,CAAC;QACX,UAAU,EAAE,CAAC;QACb,MAAM,EAAE,GAAG;QACX,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,CAAC,EAAE;QACX,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,EAAE;QACV,KAAK,EAAE,YAAY;QACnB,WAAW,EAAE,mBAAmB;QAChC,WAAW,EAAE,UAAU;QACvB,eAAe,EAAE,KAAK;QACtB,MAAM,EAAE,MAAM;KACf;CACF,CAAA","sourcesContent":["const icon = new URL('../../icons/robot-arm.png', import.meta.url).href\n\nexport default {\n type: 'robot-arm',\n description: 'articulated robot arm — configurable kinematic chain with style/gripper options and IK',\n group: 'manufacturing' /* line|shape|textAndMedia|chartAndGauge|table|container|dataSource|3D|facility|storage|conveyance|transport|manufacturing|form|etc */,\n icon,\n model: {\n type: 'robot-arm',\n top: 200,\n left: 200,\n width: 5,\n height: 5,\n depth: 80,\n rotation: 0,\n linkRadius: 2,\n joint0: 106,\n joint1: 48,\n joint2: 31,\n joint3: -26,\n joint4: 48,\n joint5: 29,\n style: 'industrial',\n chainPreset: '6-axis-industrial',\n gripperType: 'parallel',\n showReachSphere: false,\n status: 'idle'\n }\n}\n"]}
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@operato/scene-manufacturing",
|
|
3
3
|
"description": "Things scene components for manufacturing industry",
|
|
4
|
-
"version": "10.0.0-beta.
|
|
4
|
+
"version": "10.0.0-beta.28",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"things-scene": true,
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@hatiolab/things-scene": "^10.0.0-beta.1",
|
|
32
|
-
"@operato/scene-base": "^10.0.0-beta.
|
|
32
|
+
"@operato/scene-base": "^10.0.0-beta.24",
|
|
33
33
|
"three": "^0.183.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
@@ -61,5 +61,5 @@
|
|
|
61
61
|
"prettier --write"
|
|
62
62
|
]
|
|
63
63
|
},
|
|
64
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "40634f9afc681d852d6028a329cedb51cc4fb94f"
|
|
65
65
|
}
|
package/icons/tact-timer.png
DELETED
|
Binary file
|