@genex-ai/cli-demo 0.12.1 → 0.14.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.
Files changed (40) hide show
  1. package/README.md +1 -0
  2. package/dist/index.js +203 -4
  3. package/package.json +7 -2
  4. package/templates/controllers/NOTICE.md +65 -0
  5. package/templates/controllers/assets/animation-library.glb +0 -0
  6. package/templates/controllers/assets/character.glb +0 -0
  7. package/templates/controllers/assets/default-avatar.vrm +0 -0
  8. package/templates/controllers/character/character-animations.ts +682 -0
  9. package/templates/controllers/character/character-controller.ts +1636 -0
  10. package/templates/controllers/character/follow-camera.ts +644 -0
  11. package/templates/controllers/character/keyboard-input.ts +277 -0
  12. package/templates/controllers/character/presets.ts +176 -0
  13. package/templates/controllers/character/touch-joystick.ts +387 -0
  14. package/templates/controllers/character/vrm/capsule-fit.ts +52 -0
  15. package/templates/controllers/character/vrm/foot-ik.ts +341 -0
  16. package/templates/controllers/character/vrm/vrm-loader.ts +44 -0
  17. package/templates/controllers/character/vrm/vrm-retarget.ts +195 -0
  18. package/templates/controllers/drone/drone-controller.ts +1073 -0
  19. package/templates/controllers/drone/presets.ts +225 -0
  20. package/templates/controllers/interact/enter-exit.ts +502 -0
  21. package/templates/controllers/shared/colliders.ts +456 -0
  22. package/templates/controllers/shared/math.ts +230 -0
  23. package/templates/controllers/shared/physics-world.ts +622 -0
  24. package/templates/controllers/vehicle/presets.ts +297 -0
  25. package/templates/controllers/vehicle/vehicle-controller.ts +615 -0
  26. package/templates/controllers/vehicle/wheel.ts +1200 -0
  27. package/templates/skills/genex-getting-started/SKILL.md +5 -0
  28. package/templates/skills/genex-threejs-character-controller/SKILL.md +205 -0
  29. package/templates/skills/genex-threejs-character-controller/references/animations.md +235 -0
  30. package/templates/skills/genex-threejs-character-controller/references/tuning-and-presets.md +102 -0
  31. package/templates/skills/genex-threejs-character-controller/references/wiring.md +198 -0
  32. package/templates/skills/genex-threejs-physics-rapier/SKILL.md +128 -0
  33. package/templates/skills/genex-threejs-physics-rapier/references/colliders-from-assets.md +202 -0
  34. package/templates/skills/genex-threejs-physics-rapier/references/physics-setup.md +207 -0
  35. package/templates/skills/genex-threejs-skill-router/SKILL.md +3 -0
  36. package/templates/skills/genex-threejs-skill-router/references/routing-map.md +15 -7
  37. package/templates/skills/genex-threejs-vehicle-controllers/SKILL.md +110 -0
  38. package/templates/skills/genex-threejs-vehicle-controllers/references/car.md +162 -0
  39. package/templates/skills/genex-threejs-vehicle-controllers/references/drone.md +150 -0
  40. package/templates/skills/genex-threejs-vehicle-controllers/references/enter-exit.md +199 -0
@@ -0,0 +1,225 @@
1
+ // SPDX-FileCopyrightText: 2023-2026 Erdong Chen
2
+ // SPDX-License-Identifier: MIT
3
+ // Vanilla-TS port of the ecctrl drone controller (named preset tables:
4
+ // heavy-lifter is the upstream demo drone verbatim; camera-drone and
5
+ // racing-drone are product tuning derived from the library defaults).
6
+
7
+ import type { DroneConfig } from "./drone-controller.ts";
8
+
9
+ /**
10
+ * One propeller slot of a preset: where to place the mount (in chassis
11
+ * space) and how to configure it. Thrust axis is the mount's local +Y.
12
+ */
13
+ export interface DronePropellerPreset {
14
+ /** Mount position in chassis space. */
15
+ position: { x: number; y: number; z: number };
16
+ /** Max thrust in newtons at full throttle. */
17
+ maxThrust: number;
18
+ /** Reaction torque = maxThrust * torqueRatio. */
19
+ torqueRatio: number;
20
+ /**
21
+ * Counter-rotation flag. Diagonal pairs share the same value so reaction
22
+ * torques cancel at hover (quad-X layout).
23
+ */
24
+ invertTorque: boolean;
25
+ }
26
+
27
+ /**
28
+ * Collider recipe for the chassis body: one central cuboid plus one flat
29
+ * cylinder under each propeller (arm tips). Feed these to the collider
30
+ * helpers in shared/colliders.ts when building the rigid body.
31
+ */
32
+ export interface DroneBodyPreset {
33
+ cuboidHalfExtents: { x: number; y: number; z: number };
34
+ armCylinders: {
35
+ halfHeight: number;
36
+ radius: number;
37
+ positions: { x: number; y: number; z: number }[];
38
+ };
39
+ /** Collider density (kg/m^3). Rapier derives the actual mass from this. */
40
+ density: number;
41
+ /**
42
+ * Documentation value only — Rapier computes the real mass from the
43
+ * colliders. The PD POSITION gains and maxThrust in `config` assume a mass
44
+ * near this number.
45
+ */
46
+ approxMassKg: number;
47
+ }
48
+
49
+ /** A complete, ready-to-fly drone recipe. */
50
+ export interface DronePreset {
51
+ name: string;
52
+ /** Merged over DEFAULT_DRONE_CONFIG by the controller. */
53
+ config: Partial<DroneConfig>;
54
+ /** Always 4 propellers in a quad-X layout. */
55
+ propellers: DronePropellerPreset[];
56
+ body: DroneBodyPreset;
57
+ /**
58
+ * weight / (4 * maxThrust), documentation value. Attitude authority is
59
+ * best when this is near 0.5 (total thrust ~ 2x weight).
60
+ */
61
+ approxHoverThrottle: number;
62
+ /** Plain-language provenance and tuning hints. */
63
+ notes: string;
64
+ }
65
+
66
+ // All presets are quad-X: propellers at (+-ox, oy, +-oz) with invertTorque
67
+ // true on the (+x,+z) and (-x,-z) diagonal pair (counter-rotation, so the
68
+ // reaction torques cancel at hover).
69
+
70
+ /**
71
+ * Slow, heavily damped aerial-camera platform (~2 kg at density 335).
72
+ * Gentle 20-degree tilt limit, strong air drag, extra tilt damping. The
73
+ * POSITION-mode gains stay at the library defaults, which fit a ~2 kg drone.
74
+ */
75
+ export const cameraDrone: DronePreset = {
76
+ name: "camera-drone",
77
+ config: {
78
+ controlMode: "VELOCITY",
79
+ maxYawRate: 1.2,
80
+ maxHorizSpeed: 10,
81
+ maxVertSpeed: 4,
82
+ maxTiltAngle: Math.PI / 9, // 20 degrees
83
+ airDragFactor: 0.4,
84
+ TILT_D: 4,
85
+ },
86
+ propellers: [
87
+ { position: { x: 0.25, y: 0.02, z: 0.25 }, maxThrust: 10, torqueRatio: 0.6, invertTorque: true },
88
+ { position: { x: -0.25, y: 0.02, z: 0.25 }, maxThrust: 10, torqueRatio: 0.6, invertTorque: false },
89
+ { position: { x: 0.25, y: 0.02, z: -0.25 }, maxThrust: 10, torqueRatio: 0.6, invertTorque: false },
90
+ { position: { x: -0.25, y: 0.02, z: -0.25 }, maxThrust: 10, torqueRatio: 0.6, invertTorque: true },
91
+ ],
92
+ body: {
93
+ cuboidHalfExtents: { x: 0.12, y: 0.04, z: 0.12 },
94
+ armCylinders: {
95
+ halfHeight: 0.01,
96
+ radius: 0.12,
97
+ positions: [
98
+ { x: 0.25, y: 0.02, z: 0.25 },
99
+ { x: -0.25, y: 0.02, z: 0.25 },
100
+ { x: 0.25, y: 0.02, z: -0.25 },
101
+ { x: -0.25, y: 0.02, z: -0.25 },
102
+ ],
103
+ },
104
+ density: 335,
105
+ approxMassKg: 2,
106
+ },
107
+ approxHoverThrottle: 0.49,
108
+ notes:
109
+ "Steady filming platform, assumes a ~2 kg body (density 335). Hover sits " +
110
+ "near 0.49 throttle, so attitude authority is close to its best. Feels " +
111
+ "floaty on purpose: high air drag and extra tilt damping smooth out " +
112
+ "stick input. If you change the mass, scale maxThrust to keep hover near " +
113
+ "0.5 and scale VERT_POS_/HORIZ_POS_ gains linearly with mass.",
114
+ };
115
+
116
+ /**
117
+ * Agile FPV-style racer (~5 kg at density 240). Full 45-degree tilt, fast
118
+ * yaw, low drag, snappier tilt response.
119
+ */
120
+ export const racingDrone: DronePreset = {
121
+ name: "racing-drone",
122
+ config: {
123
+ controlMode: "VELOCITY",
124
+ maxYawRate: 3.5,
125
+ maxVertSpeed: 12,
126
+ airDragFactor: 0.15,
127
+ TILT_P: 18,
128
+ TILT_D: 2.5,
129
+ },
130
+ propellers: [
131
+ { position: { x: 0.3, y: 0.02, z: 0.3 }, maxThrust: 25, torqueRatio: 0.6, invertTorque: true },
132
+ { position: { x: -0.3, y: 0.02, z: 0.3 }, maxThrust: 25, torqueRatio: 0.6, invertTorque: false },
133
+ { position: { x: 0.3, y: 0.02, z: -0.3 }, maxThrust: 25, torqueRatio: 0.6, invertTorque: false },
134
+ { position: { x: -0.3, y: 0.02, z: -0.3 }, maxThrust: 25, torqueRatio: 0.6, invertTorque: true },
135
+ ],
136
+ body: {
137
+ cuboidHalfExtents: { x: 0.15, y: 0.05, z: 0.2 },
138
+ armCylinders: {
139
+ halfHeight: 0.01,
140
+ radius: 0.15,
141
+ positions: [
142
+ { x: 0.3, y: 0.02, z: 0.3 },
143
+ { x: -0.3, y: 0.02, z: 0.3 },
144
+ { x: 0.3, y: 0.02, z: -0.3 },
145
+ { x: -0.3, y: 0.02, z: -0.3 },
146
+ ],
147
+ },
148
+ density: 240,
149
+ approxMassKg: 5,
150
+ },
151
+ approxHoverThrottle: 0.49,
152
+ notes:
153
+ "Fast and twitchy, assumes a ~5 kg body (density 240). Full 45-degree " +
154
+ "tilt at 30 m/s (library default) with quick yaw. Raise TILT_P for even " +
155
+ "sharper flips, raise TILT_D if it wobbles after a maneuver. POSITION " +
156
+ "gains stay at library defaults, sized for a light drone; scale them " +
157
+ "with mass if you make it heavier.",
158
+ };
159
+
160
+ /**
161
+ * The upstream demo drone, verbatim (~298 kg at density 200): big cargo
162
+ * platform with POSITION gains pre-scaled x100 for its mass.
163
+ */
164
+ export const heavyLifter: DronePreset = {
165
+ name: "heavy-lifter",
166
+ config: {
167
+ controlMode: "VELOCITY",
168
+ maxYawRate: 2,
169
+ maxHorizSpeed: 20,
170
+ maxVertSpeed: 8,
171
+ maxTiltAngle: Math.PI / 4,
172
+ airDragFactor: 0.2,
173
+ TILT_P: 15,
174
+ TILT_D: 3,
175
+ // Yaw gains stay at library defaults (6 / 4) — matches the demo.
176
+ VERT_POS_P: 900,
177
+ VERT_POS_D: 700,
178
+ HORIZ_POS_P: 500,
179
+ HORIZ_POS_D: 550,
180
+ HORIZ_VEL_P: 1,
181
+ VERT_VEL_P: 2,
182
+ },
183
+ propellers: [
184
+ { position: { x: 1, y: -0.15, z: 1 }, maxThrust: 5000, torqueRatio: 0.6, invertTorque: true },
185
+ { position: { x: -1, y: -0.15, z: 1 }, maxThrust: 5000, torqueRatio: 0.6, invertTorque: false },
186
+ { position: { x: 1, y: -0.15, z: -1 }, maxThrust: 5000, torqueRatio: 0.6, invertTorque: false },
187
+ { position: { x: -1, y: -0.15, z: -1 }, maxThrust: 5000, torqueRatio: 0.6, invertTorque: true },
188
+ ],
189
+ body: {
190
+ cuboidHalfExtents: { x: 0.4, y: 0.2, z: 1.5 },
191
+ armCylinders: {
192
+ halfHeight: 0.05,
193
+ radius: 0.65,
194
+ positions: [
195
+ { x: 1, y: -0.15, z: 1 },
196
+ { x: 1, y: -0.15, z: -1 },
197
+ { x: -1, y: -0.15, z: 1 },
198
+ { x: -1, y: -0.15, z: -1 },
199
+ ],
200
+ },
201
+ density: 200,
202
+ approxMassKg: 298,
203
+ },
204
+ approxHoverThrottle: 0.146,
205
+ notes:
206
+ "The original demo drone, kept number-for-number: a ~298 kg lifter " +
207
+ "(density 200, cuboid ~192 kg plus four ~26.5 kg arm discs). Hover sits " +
208
+ "low at ~0.146 throttle, so it has huge climb reserve but less attitude " +
209
+ "budget. Its VERT_POS_/HORIZ_POS_ hold gains are pre-scaled about x100 " +
210
+ "over the library defaults because those gains are absolute forces that " +
211
+ "grow with mass. Good for cargo craft and boss vehicles. Note the " +
212
+ "airDragFactor 0.2 is nearly cosmetic at this mass.",
213
+ };
214
+
215
+ /**
216
+ * All shipped drone presets by kebab-case name. Spread a preset's `config`
217
+ * into DroneControllerOptions and build body/propellers from its recipes.
218
+ */
219
+ export const dronePresets: Readonly<
220
+ Record<"camera-drone" | "racing-drone" | "heavy-lifter", DronePreset>
221
+ > = {
222
+ "camera-drone": cameraDrone,
223
+ "racing-drone": racingDrone,
224
+ "heavy-lifter": heavyLifter,
225
+ };