@holoscript/robotics-plugin 2.0.1 → 2.0.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.
package/package.json CHANGED
@@ -1,8 +1,14 @@
1
1
  {
2
2
  "name": "@holoscript/robotics-plugin",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "HoloScript plugin for robotics: compile-time USD/URDF codegen + runtime ROS2/Gazebo integration. VR robot programming and digital twins.",
5
5
  "main": "src/index.ts",
6
+ "scripts": {
7
+ "build": "tsc",
8
+ "test": "vitest run",
9
+ "clean": "rimraf dist",
10
+ "test:coverage": "vitest run --coverage"
11
+ },
6
12
  "keywords": [
7
13
  "holoscript",
8
14
  "plugin",
@@ -17,15 +23,9 @@
17
23
  "author": "HoloScript Contributors",
18
24
  "license": "MIT",
19
25
  "peerDependencies": {
20
- "@holoscript/core": "8.0.6"
26
+ "@holoscript/core": ">=8.0.0"
21
27
  },
22
28
  "engines": {
23
29
  "node": ">=20.0.0"
24
- },
25
- "scripts": {
26
- "build": "tsc",
27
- "test": "vitest run",
28
- "clean": "rimraf dist",
29
- "test:coverage": "vitest run --coverage"
30
30
  }
31
- }
31
+ }
@@ -92,12 +92,7 @@ describe('Isaac Lab Interop (Path A)', () => {
92
92
  expect(ast.domainRandomization?.actuator?.kdNoise).toBe(0.05);
93
93
  expect(ast.domainRandomization?.initialState?.jointPosRange?.joint1).toEqual([-0.1, 0.1]);
94
94
  expect(ast.domainRandomization?.initialState?.rootPoseRange).toEqual([
95
- -0.5,
96
- 0.5,
97
- -0.5,
98
- 0.5,
99
- 0,
100
- 1,
95
+ -0.5, 0.5, -0.5, 0.5, 0, 1,
101
96
  ]);
102
97
  });
103
98
 
@@ -133,8 +128,12 @@ describe('Isaac Lab Interop (Path A)', () => {
133
128
  expect(usd).toContain('# Generated for Isaac Lab 2.3');
134
129
  expect(usd).toContain('metersPerUnit = 1.0');
135
130
  expect(usd).toContain('kilogramsPerMass = 1.0');
136
- expect(usd).toContain('# Units: meters, kilograms, seconds; HoloScript angular inputs are radians.');
137
- expect(usd).toContain('prepend apiSchemas = ["PhysicsArticulationRootAPI", "PhysxArticulationAPI"]');
131
+ expect(usd).toContain(
132
+ '# Units: meters, kilograms, seconds; HoloScript angular inputs are radians.'
133
+ );
134
+ expect(usd).toContain(
135
+ 'prepend apiSchemas = ["PhysicsArticulationRootAPI", "PhysxArticulationAPI"]'
136
+ );
138
137
  expect(usd).toContain('bool physxArticulation:articulationEnabled = true');
139
138
  expect(usd).not.toContain('physxArticulation:jointFriction');
140
139
  });
@@ -142,7 +141,9 @@ describe('Isaac Lab Interop (Path A)', () => {
142
141
  it('emits applied DriveAPI and PhysxJointAxisAPI schemas on actuated joints', () => {
143
142
  const usd = new USDCodeGen().generate(parseHoloScript());
144
143
 
145
- expect(usd).toContain('prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysxJointAxisAPI:angular"]');
144
+ expect(usd).toContain(
145
+ 'prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysxJointAxisAPI:angular"]'
146
+ );
146
147
  expect(usd).toContain('float drive:angular:physics:stiffness = 100');
147
148
  expect(usd).toContain('float drive:angular:physics:damping = 10');
148
149
  expect(usd).toContain('float drive:angular:physics:maxForce = 50');
@@ -173,7 +174,9 @@ describe('Isaac Lab Interop (Path A)', () => {
173
174
  expect(usd).toContain('# kpNoise: 0.1');
174
175
  expect(usd).toContain('# kdNoise: 0.05');
175
176
  expect(usd).toContain('custom float holoscript:isaacLab:actuatorLatencySeconds = 0.005');
176
- expect(usd).toContain('# arm_group: type=DelayedPDActuator joints=[joint1, joint2, joint3]');
177
+ expect(usd).toContain(
178
+ '# arm_group: type=DelayedPDActuator joints=[joint1, joint2, joint3]'
179
+ );
177
180
  });
178
181
 
179
182
  it('disables DriveAPI and PhysX joint-axis output when configured off', () => {
package/src/ast.ts CHANGED
@@ -43,7 +43,12 @@ export interface DomainRandomizationConfig {
43
43
 
44
44
  export interface ActuatorGroupConfig {
45
45
  name: string;
46
- type: 'IdealPDActuator' | 'DCMotorActuator' | 'DelayedPDActuator' | 'RemotizedPDActuator' | 'ImplicitActuator';
46
+ type:
47
+ | 'IdealPDActuator'
48
+ | 'DCMotorActuator'
49
+ | 'DelayedPDActuator'
50
+ | 'RemotizedPDActuator'
51
+ | 'ImplicitActuator';
47
52
  jointNames: string[];
48
53
  stiffness?: number;
49
54
  damping?: number;
package/src/index.ts CHANGED
@@ -148,15 +148,16 @@ function asString(value: unknown, fallback: string): string {
148
148
 
149
149
  function asVec3(value: unknown, fallback: [number, number, number]): [number, number, number] {
150
150
  if (Array.isArray(value) && value.length >= 3) {
151
- return [asNumber(value[0], fallback[0]), asNumber(value[1], fallback[1]), asNumber(value[2], fallback[2])];
151
+ return [
152
+ asNumber(value[0], fallback[0]),
153
+ asNumber(value[1], fallback[1]),
154
+ asNumber(value[2], fallback[2]),
155
+ ];
152
156
  }
153
157
  return fallback;
154
158
  }
155
159
 
156
- function asJointLimits(
157
- value: unknown,
158
- fallback: RobotJoint['limits']
159
- ): RobotJoint['limits'] {
160
+ function asJointLimits(value: unknown, fallback: RobotJoint['limits']): RobotJoint['limits'] {
160
161
  if (Array.isArray(value) && value.length >= 4) {
161
162
  return {
162
163
  lower: asNumber(value[0], fallback?.lower ?? -1.57),
@@ -179,7 +180,10 @@ function asJointLimits(
179
180
  return fallback;
180
181
  }
181
182
 
182
- function findTrait(node: HoloCompositionNodeLike, predicate: (normalizedName: string) => boolean): TraitMatch | null {
183
+ function findTrait(
184
+ node: HoloCompositionNodeLike,
185
+ predicate: (normalizedName: string) => boolean
186
+ ): TraitMatch | null {
183
187
  for (const trait of node.traits ?? []) {
184
188
  const normalizedName = normalizeTraitName(trait.name);
185
189
  if (predicate(normalizedName)) {
@@ -193,11 +197,7 @@ function findTrait(node: HoloCompositionNodeLike, predicate: (normalizedName: st
193
197
  function getJointTrait(node: HoloCompositionNodeLike): TraitMatch | null {
194
198
  return findTrait(
195
199
  node,
196
- (name) =>
197
- name === 'joint' ||
198
- name === 'hinge' ||
199
- name === 'slider' ||
200
- name.startsWith('joint_')
200
+ (name) => name === 'joint' || name === 'hinge' || name === 'slider' || name.startsWith('joint_')
201
201
  );
202
202
  }
203
203
 
@@ -213,7 +213,9 @@ function jointTypeFromTrait(
213
213
  nodeProps: Record<string, unknown>,
214
214
  defaultJointType: RobotJoint['type']
215
215
  ): RobotJoint['type'] {
216
- const explicitType = normalizeTraitName(asString(nodeProps.joint_type ?? nodeProps.type, defaultJointType));
216
+ const explicitType = normalizeTraitName(
217
+ asString(nodeProps.joint_type ?? nodeProps.type, defaultJointType)
218
+ );
217
219
 
218
220
  switch (explicitType) {
219
221
  case 'revolute':
@@ -246,7 +248,9 @@ function jointTypeFromTrait(
246
248
  function hardwareInterfaceFromMotor(
247
249
  motorProps: Record<string, unknown>
248
250
  ): RobotTransmission['hardwareInterface'] {
249
- const commandMode = normalizeTraitName(asString(motorProps.commandMode ?? motorProps.mode, 'position'));
251
+ const commandMode = normalizeTraitName(
252
+ asString(motorProps.commandMode ?? motorProps.mode, 'position')
253
+ );
250
254
 
251
255
  if (commandMode === 'velocity') return 'velocity';
252
256
  if (commandMode === 'effort' || commandMode === 'torque') return 'effort';
@@ -291,8 +295,14 @@ function createTransmission(
291
295
  return {
292
296
  name: sanitizeRobotName(asString(motorProps.name, `${jointName}_transmission`)),
293
297
  joint: jointName,
294
- actuator: sanitizeRobotName(asString(motorProps.actuator ?? motorProps.name, `${jointName}_motor`)),
295
- mechanicalReduction: Number((asNumber(motorProps.mechanicalReduction ?? motorProps.gearRatio, 1) * hardwareScale).toFixed(6)),
298
+ actuator: sanitizeRobotName(
299
+ asString(motorProps.actuator ?? motorProps.name, `${jointName}_motor`)
300
+ ),
301
+ mechanicalReduction: Number(
302
+ (asNumber(motorProps.mechanicalReduction ?? motorProps.gearRatio, 1) * hardwareScale).toFixed(
303
+ 6
304
+ )
305
+ ),
296
306
  hardwareInterface: hardwareInterfaceFromMotor(motorProps),
297
307
  };
298
308
  }
@@ -321,7 +331,9 @@ function buildLinkXml(link: RobotLink): string {
321
331
 
322
332
  if (link.collision) {
323
333
  lines.push(' <collision>');
324
- lines.push(` <geometry><mesh filename="${xmlEscape(link.collision.geometry)}"/></geometry>`);
334
+ lines.push(
335
+ ` <geometry><mesh filename="${xmlEscape(link.collision.geometry)}"/></geometry>`
336
+ );
325
337
  lines.push(' </collision>');
326
338
  }
327
339
 
@@ -383,10 +395,7 @@ export function extractURDFFromHoloComposition(
383
395
  const joints: RobotJoint[] = [];
384
396
  const transmissions: RobotTransmission[] = [];
385
397
 
386
- const visitNode = (
387
- node: HoloCompositionNodeLike,
388
- parentLinkName: string | null
389
- ) => {
398
+ const visitNode = (node: HoloCompositionNodeLike, parentLinkName: string | null) => {
390
399
  const props = asRecord(node.properties);
391
400
  const link = mapNodeToRobotLink(node, hardwareScale);
392
401
  links.push(link);
@@ -529,7 +538,7 @@ export function generateIsaacLabFeed(
529
538
  };
530
539
 
531
540
  // Simple content hashes for the receipt (evidence loop)
532
- const sourceHoloHash = `holo:${ast.name}:${(ast.objects?.length || 0)}`;
541
+ const sourceHoloHash = `holo:${ast.name}:${ast.objects?.length || 0}`;
533
542
  const usdHash = `usd:${usd.length}`;
534
543
  const configHash = `cfg:${JSON.stringify(taskConfig).length}`;
535
544
 
@@ -540,7 +549,8 @@ export function generateIsaacLabFeed(
540
549
  generatedAt: new Date().toISOString(),
541
550
  isaacLabVersion: version,
542
551
  readyForTraining: true,
543
- notes: 'Narrow feed bundle — assets + randomization + actuator config. Policy training & real-robot eval are downstream.',
552
+ notes:
553
+ 'Narrow feed bundle — assets + randomization + actuator config. Policy training & real-robot eval are downstream.',
544
554
  };
545
555
 
546
556
  return {
package/src/parser.ts CHANGED
@@ -6,7 +6,13 @@
6
6
  */
7
7
 
8
8
  import { Token, TokenType } from './lexer';
9
- import { CompositionNode, ObjectNode, PropertyValue, DomainRandomizationConfig, ActuatorGroupConfig } from './ast';
9
+ import {
10
+ CompositionNode,
11
+ ObjectNode,
12
+ PropertyValue,
13
+ DomainRandomizationConfig,
14
+ ActuatorGroupConfig,
15
+ } from './ast';
10
16
 
11
17
  export class Parser {
12
18
  private tokens: Token[];
@@ -74,8 +80,10 @@ export class Parser {
74
80
  this.currentToken().type !== TokenType.EOF
75
81
  ) {
76
82
  // Check for domain_randomization block at composition level
77
- if (this.currentToken().type === TokenType.IDENTIFIER &&
78
- this.currentToken().value === 'domain_randomization') {
83
+ if (
84
+ this.currentToken().type === TokenType.IDENTIFIER &&
85
+ this.currentToken().value === 'domain_randomization'
86
+ ) {
79
87
  this.advance();
80
88
  this.expect(TokenType.COLON);
81
89
  domainRandomization = this.parseDomainRandomizationBlock();
@@ -125,15 +133,19 @@ export class Parser {
125
133
  }
126
134
  }
127
135
  // Check for domain_randomization block
128
- else if (this.currentToken().type === TokenType.IDENTIFIER &&
129
- this.currentToken().value === 'domain_randomization') {
136
+ else if (
137
+ this.currentToken().type === TokenType.IDENTIFIER &&
138
+ this.currentToken().value === 'domain_randomization'
139
+ ) {
130
140
  this.advance();
131
141
  this.expect(TokenType.COLON);
132
142
  domainRandomization = this.parseDomainRandomizationBlock();
133
143
  }
134
144
  // Check for actuator_group block
135
- else if (this.currentToken().type === TokenType.IDENTIFIER &&
136
- this.currentToken().value === 'actuator_group') {
145
+ else if (
146
+ this.currentToken().type === TokenType.IDENTIFIER &&
147
+ this.currentToken().value === 'actuator_group'
148
+ ) {
137
149
  this.advance();
138
150
  this.expect(TokenType.COLON);
139
151
  const group = this.parseActuatorGroupBlock();
@@ -18,9 +18,19 @@ import type { TraitHandler, HSPlusNode, TraitContext, TraitEvent } from './types
18
18
  export function createROS2HardwareLoopHandler(): TraitHandler<ROS2Config> {
19
19
  return {
20
20
  name: 'ros2_hardware_loop',
21
- defaultConfig: { nodeName: 'holo_rig_01', topicPrefix: '/holo', updateFrequencyHz: 60, bidirectional: true },
21
+ defaultConfig: {
22
+ nodeName: 'holo_rig_01',
23
+ topicPrefix: '/holo',
24
+ updateFrequencyHz: 60,
25
+ bidirectional: true,
26
+ },
22
27
  onAttach(n: unknown, c: ROS2Config, ctx: unknown) {
23
- (n as any).__ros2State = { connected: false, lastPingMs: 0, activeTopics: [], hardwareSyncDriftMs: 0 };
28
+ (n as any).__ros2State = {
29
+ connected: false,
30
+ lastPingMs: 0,
31
+ activeTopics: [],
32
+ hardwareSyncDriftMs: 0,
33
+ };
24
34
  (ctx as any).emit?.('ros2:init', { node: c.nodeName });
25
35
  },
26
36
  onDetach(n: unknown, _c: ROS2Config, ctx: unknown) {
@@ -32,38 +42,43 @@ export function createROS2HardwareLoopHandler(): TraitHandler<ROS2Config> {
32
42
  const s = (n as any).__ros2State as ROS2State;
33
43
  if (!s) return;
34
44
  const evt = e as any;
35
-
45
+
36
46
  switch (evt.type) {
37
47
  case 'ros2:connect':
38
48
  s.connected = true;
39
49
  // In real usage, initializes rclnodejs bridge for pub/sub physics
40
50
  (ctx as any).emit?.('ros2:connected', { latencyMs: 12 });
41
51
  break;
42
-
52
+
43
53
  case 'scene:transform_change':
44
54
  if (c.bidirectional && s.connected) {
45
55
  // Push virtual set transform to physical robot joint
46
- (ctx as any).emit?.('ros2:publish', { topic: `${c.topicPrefix}/joint_cmd`, payload: evt.payload });
56
+ (ctx as any).emit?.('ros2:publish', {
57
+ topic: `${c.topicPrefix}/joint_cmd`,
58
+ payload: evt.payload,
59
+ });
47
60
  }
48
- break;
49
-
61
+ break;
62
+
50
63
  case 'ros2:telemetry':
51
64
  // Receive physical robot telemetry to drive virtual set
52
65
  s.hardwareSyncDriftMs = Math.abs(Date.now() - (evt.payload.timestamp || Date.now()));
53
- (n as any).transform = evt.payload.transform;
66
+ (n as any).transform = evt.payload.transform;
54
67
  break;
55
-
68
+
56
69
  case 'ttu:manifested':
57
70
  // Dynamically bind to Text-To-Universe AST streams
58
71
  const crdtRoot = evt.payload?.crdtRoot;
59
72
  if (crdtRoot && s.connected) {
60
- const dynamicTopic = `${c.topicPrefix}/ttu_sync/${crdtRoot}`;
61
- s.activeTopics.push(dynamicTopic);
62
- (ctx as any).emit?.('ros2:subscribe', { topic: dynamicTopic });
63
- (ctx as any).emit?.('ros2:log', { message: `Bridged digital twin for TTU root: ${crdtRoot}` });
73
+ const dynamicTopic = `${c.topicPrefix}/ttu_sync/${crdtRoot}`;
74
+ s.activeTopics.push(dynamicTopic);
75
+ (ctx as any).emit?.('ros2:subscribe', { topic: dynamicTopic });
76
+ (ctx as any).emit?.('ros2:log', {
77
+ message: `Bridged digital twin for TTU root: ${crdtRoot}`,
78
+ });
64
79
  }
65
80
  break;
66
81
  }
67
- }
82
+ },
68
83
  };
69
84
  }
@@ -61,7 +61,9 @@ export class USDCodeGen {
61
61
  // Isaac Lab header comment
62
62
  this.emit(`# Generated for Isaac Lab ${this.config.isaacLabVersion}`);
63
63
  this.emit('# Units: meters, kilograms, seconds; HoloScript angular inputs are radians.');
64
- this.emit('# USD angular joint limits and velocities are exported in degrees per OpenUSD/PhysX.');
64
+ this.emit(
65
+ '# USD angular joint limits and velocities are exported in degrees per OpenUSD/PhysX.'
66
+ );
65
67
 
66
68
  // Emit domain randomization config as USD comments (for Isaac Lab Python codegen)
67
69
  if (ast.domainRandomization) {
@@ -316,7 +318,9 @@ export class USDCodeGen {
316
318
  const schemas = this.getJointApiSchemas(joint, axisToken);
317
319
 
318
320
  this.emit('');
319
- this.emit(`def ${joint.kind === 'prismatic' ? 'PhysicsPrismaticJoint' : 'PhysicsRevoluteJoint'} "${joint.name}"`);
321
+ this.emit(
322
+ `def ${joint.kind === 'prismatic' ? 'PhysicsPrismaticJoint' : 'PhysicsRevoluteJoint'} "${joint.name}"`
323
+ );
320
324
  if (schemas.length > 0) {
321
325
  this.emit('(');
322
326
  this.indentLevel++;
@@ -361,8 +365,12 @@ export class USDCodeGen {
361
365
  const limits = joint.props.joint_limits || joint.props.limits;
362
366
  if (limits) {
363
367
  const limitsVec = limits as number[];
364
- this.emit(`float physics:lowerLimit = ${this.formatNumber(this.convertJointScalar(limitsVec[0], joint.kind))}`);
365
- this.emit(`float physics:upperLimit = ${this.formatNumber(this.convertJointScalar(limitsVec[1], joint.kind))}`);
368
+ this.emit(
369
+ `float physics:lowerLimit = ${this.formatNumber(this.convertJointScalar(limitsVec[0], joint.kind))}`
370
+ );
371
+ this.emit(
372
+ `float physics:upperLimit = ${this.formatNumber(this.convertJointScalar(limitsVec[1], joint.kind))}`
373
+ );
366
374
  }
367
375
  this.emit('');
368
376
 
@@ -374,7 +382,9 @@ export class USDCodeGen {
374
382
 
375
383
  const velocity = this.numberProp(joint.props, 'max_velocity');
376
384
  if (velocity !== undefined) {
377
- this.emit(`float physics:maxVelocity = ${this.formatNumber(this.convertJointScalar(velocity, joint.kind))}`);
385
+ this.emit(
386
+ `float physics:maxVelocity = ${this.formatNumber(this.convertJointScalar(velocity, joint.kind))}`
387
+ );
378
388
  }
379
389
 
380
390
  // OpenUSD PhysicsDriveAPI attributes for PD actuator control.
@@ -406,7 +416,9 @@ export class USDCodeGen {
406
416
  const latency = this.numberProp(joint.props, 'actuator_latency', 'latency');
407
417
  if (latency !== undefined) {
408
418
  this.emit('');
409
- this.emit('# Isaac Lab delayed actuator hint; convert seconds to delay steps in task config.');
419
+ this.emit(
420
+ '# Isaac Lab delayed actuator hint; convert seconds to delay steps in task config.'
421
+ );
410
422
  this.emit(`custom float holoscript:isaacLab:actuatorLatencySeconds = ${latency}`);
411
423
  }
412
424
 
@@ -468,7 +480,10 @@ export class USDCodeGen {
468
480
  }
469
481
 
470
482
  private hasDriveProperties(props: Record<string, PropertyValue>): boolean {
471
- return this.numberProp(props, 'kp', 'stiffness', 'kd', 'damping', 'joint_effort', 'max_effort') !== undefined;
483
+ return (
484
+ this.numberProp(props, 'kp', 'stiffness', 'kd', 'damping', 'joint_effort', 'max_effort') !==
485
+ undefined
486
+ );
472
487
  }
473
488
 
474
489
  private hasPhysxJointAxisProperties(props: Record<string, PropertyValue>): boolean {
@@ -505,13 +520,17 @@ export class USDCodeGen {
505
520
  this.emit(`float physxJointAxis:${axisToken}:dynamicFrictionEffort = ${dynamicFriction}`);
506
521
  }
507
522
  if (viscousFriction !== undefined) {
508
- this.emit(`float physxJointAxis:${axisToken}:viscousFrictionCoefficient = ${viscousFriction}`);
523
+ this.emit(
524
+ `float physxJointAxis:${axisToken}:viscousFrictionCoefficient = ${viscousFriction}`
525
+ );
509
526
  }
510
527
  if (armature !== undefined) {
511
528
  this.emit(`float physxJointAxis:${axisToken}:armature = ${armature}`);
512
529
  }
513
530
  if (velocity !== undefined) {
514
- this.emit(`float physxJointAxis:${axisToken}:maxJointVelocity = ${this.formatNumber(this.convertJointScalar(velocity, kind))}`);
531
+ this.emit(
532
+ `float physxJointAxis:${axisToken}:maxJointVelocity = ${this.formatNumber(this.convertJointScalar(velocity, kind))}`
533
+ );
515
534
  }
516
535
  }
517
536
 
@@ -570,13 +589,19 @@ export class USDCodeGen {
570
589
  this.emit(`# massScale: [${dr.physics.massScale[0]}, ${dr.physics.massScale[1]}]`);
571
590
  }
572
591
  if (dr.physics.frictionRange) {
573
- this.emit(`# frictionRange: [${dr.physics.frictionRange[0]}, ${dr.physics.frictionRange[1]}]`);
592
+ this.emit(
593
+ `# frictionRange: [${dr.physics.frictionRange[0]}, ${dr.physics.frictionRange[1]}]`
594
+ );
574
595
  }
575
596
  if (dr.physics.dampingRange) {
576
- this.emit(`# dampingRange: [${dr.physics.dampingRange[0]}, ${dr.physics.dampingRange[1]}]`);
597
+ this.emit(
598
+ `# dampingRange: [${dr.physics.dampingRange[0]}, ${dr.physics.dampingRange[1]}]`
599
+ );
577
600
  }
578
601
  if (dr.physics.armatureRange) {
579
- this.emit(`# armatureRange: [${dr.physics.armatureRange[0]}, ${dr.physics.armatureRange[1]}]`);
602
+ this.emit(
603
+ `# armatureRange: [${dr.physics.armatureRange[0]}, ${dr.physics.armatureRange[1]}]`
604
+ );
580
605
  }
581
606
  }
582
607
  if (dr.actuator) {
@@ -612,10 +637,14 @@ export class USDCodeGen {
612
637
  if (dr.disturbance) {
613
638
  this.emit('# disturbance:');
614
639
  if (dr.disturbance.forceRange) {
615
- this.emit(`# forceRange: [${dr.disturbance.forceRange[0]}, ${dr.disturbance.forceRange[1]}]`);
640
+ this.emit(
641
+ `# forceRange: [${dr.disturbance.forceRange[0]}, ${dr.disturbance.forceRange[1]}]`
642
+ );
616
643
  }
617
644
  if (dr.disturbance.intervalRange) {
618
- this.emit(`# intervalRange: [${dr.disturbance.intervalRange[0]}, ${dr.disturbance.intervalRange[1]}]`);
645
+ this.emit(
646
+ `# intervalRange: [${dr.disturbance.intervalRange[0]}, ${dr.disturbance.intervalRange[1]}]`
647
+ );
619
648
  }
620
649
  }
621
650
  }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2025-2026 HoloScript Contributors
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
package/dist/ast.d.ts DELETED
@@ -1,69 +0,0 @@
1
- /**
2
- * Abstract Syntax Tree (AST) node types for HoloScript robotics
3
- *
4
- * Extended for Isaac Lab sim-to-real interop (Path A):
5
- * - Domain randomization blocks
6
- * - Actuator group configurations
7
- * - Delayed actuator export hints
8
- */
9
- export type PropertyValue = string | number | boolean | number[] | PropertyValue[];
10
- export interface DomainRandomizationConfig {
11
- /** Physics randomization: mass, friction, damping */
12
- physics?: {
13
- massScale?: [number, number];
14
- frictionRange?: [number, number];
15
- dampingRange?: [number, number];
16
- armatureRange?: [number, number];
17
- };
18
- /** Actuator randomization */
19
- actuator?: {
20
- kpNoise?: number;
21
- kdNoise?: number;
22
- latencyNoise?: number;
23
- };
24
- /** Observation noise */
25
- observation?: {
26
- jointPosNoise?: number;
27
- jointVelNoise?: number;
28
- imuNoise?: number;
29
- };
30
- /** Initial state randomization */
31
- initialState?: {
32
- jointPosRange?: Record<string, [number, number]>;
33
- rootPoseRange?: [number, number, number, number, number, number];
34
- };
35
- /** Disturbance forces */
36
- disturbance?: {
37
- forceRange?: [number, number];
38
- intervalRange?: [number, number];
39
- };
40
- }
41
- export interface ActuatorGroupConfig {
42
- name: string;
43
- type: 'IdealPDActuator' | 'DCMotorActuator' | 'DelayedPDActuator' | 'RemotizedPDActuator' | 'ImplicitActuator';
44
- jointNames: string[];
45
- stiffness?: number;
46
- damping?: number;
47
- friction?: number;
48
- latency?: number;
49
- }
50
- export interface ObjectNode {
51
- type: 'object';
52
- name: string;
53
- traits: string[];
54
- properties: Record<string, PropertyValue>;
55
- domainRandomization?: DomainRandomizationConfig;
56
- actuatorGroups?: ActuatorGroupConfig[];
57
- template?: string;
58
- line?: number;
59
- column?: number;
60
- }
61
- export interface CompositionNode {
62
- type: 'composition';
63
- name: string;
64
- objects: ObjectNode[];
65
- domainRandomization?: DomainRandomizationConfig;
66
- line?: number;
67
- column?: number;
68
- }
69
- export type ASTNode = CompositionNode | ObjectNode;
package/dist/ast.js DELETED
@@ -1,9 +0,0 @@
1
- /**
2
- * Abstract Syntax Tree (AST) node types for HoloScript robotics
3
- *
4
- * Extended for Isaac Lab sim-to-real interop (Path A):
5
- * - Domain randomization blocks
6
- * - Actuator group configurations
7
- * - Delayed actuator export hints
8
- */
9
- export {};