@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.
- package/README.md +1 -0
- package/dist/index.js +203 -4
- package/package.json +7 -2
- package/templates/controllers/NOTICE.md +65 -0
- package/templates/controllers/assets/animation-library.glb +0 -0
- package/templates/controllers/assets/character.glb +0 -0
- package/templates/controllers/assets/default-avatar.vrm +0 -0
- package/templates/controllers/character/character-animations.ts +682 -0
- package/templates/controllers/character/character-controller.ts +1636 -0
- package/templates/controllers/character/follow-camera.ts +644 -0
- package/templates/controllers/character/keyboard-input.ts +277 -0
- package/templates/controllers/character/presets.ts +176 -0
- package/templates/controllers/character/touch-joystick.ts +387 -0
- package/templates/controllers/character/vrm/capsule-fit.ts +52 -0
- package/templates/controllers/character/vrm/foot-ik.ts +341 -0
- package/templates/controllers/character/vrm/vrm-loader.ts +44 -0
- package/templates/controllers/character/vrm/vrm-retarget.ts +195 -0
- package/templates/controllers/drone/drone-controller.ts +1073 -0
- package/templates/controllers/drone/presets.ts +225 -0
- package/templates/controllers/interact/enter-exit.ts +502 -0
- package/templates/controllers/shared/colliders.ts +456 -0
- package/templates/controllers/shared/math.ts +230 -0
- package/templates/controllers/shared/physics-world.ts +622 -0
- package/templates/controllers/vehicle/presets.ts +297 -0
- package/templates/controllers/vehicle/vehicle-controller.ts +615 -0
- package/templates/controllers/vehicle/wheel.ts +1200 -0
- package/templates/skills/genex-getting-started/SKILL.md +5 -0
- package/templates/skills/genex-threejs-character-controller/SKILL.md +205 -0
- package/templates/skills/genex-threejs-character-controller/references/animations.md +235 -0
- package/templates/skills/genex-threejs-character-controller/references/tuning-and-presets.md +102 -0
- package/templates/skills/genex-threejs-character-controller/references/wiring.md +198 -0
- package/templates/skills/genex-threejs-physics-rapier/SKILL.md +128 -0
- package/templates/skills/genex-threejs-physics-rapier/references/colliders-from-assets.md +202 -0
- package/templates/skills/genex-threejs-physics-rapier/references/physics-setup.md +207 -0
- package/templates/skills/genex-threejs-skill-router/SKILL.md +3 -0
- package/templates/skills/genex-threejs-skill-router/references/routing-map.md +15 -7
- package/templates/skills/genex-threejs-vehicle-controllers/SKILL.md +110 -0
- package/templates/skills/genex-threejs-vehicle-controllers/references/car.md +162 -0
- package/templates/skills/genex-threejs-vehicle-controllers/references/drone.md +150 -0
- 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
|
+
};
|