ReviewOS

also looking at this

stacks/drone

feat: expose owned VTOL transition simulation through native CLI

#82
Merged chris wants to merge codex/owned-vtol-transition-cli into main
20 files +743 -36
app/Commands/VtolSimulate.tsadded+28-0
Changes to app/Commands/VtolSimulate.ts
@@ -0,0 +1,28 @@
1import { defineCommand } from '@stacksjs/cli'
2import { print, printError } from '@stacksjs/cli/output'
3import { createVtolTransitionProfile } from '../../resources/functions/drone/vehicles/vtol/transition-profile'
4import { runVehicleSimulation } from '../../resources/functions/drone/vehicles/runtime'
5
6export default defineCommand({
7 name: 'vtol:simulate',
8 description: 'Exercise the fictional owned front/cruise/back/landing route; no physical control',
9 options: {
10 '--seconds <n>': { description: 'Maximum virtual duration, 2..180 seconds', default: '160' },
11 '--electrical': { description: 'Use fictional electrical load and delayed battery measurements', default: false },
12 },
13 handle(options) {
14 try {
15 const result = runVehicleSimulation(createVtolTransitionProfile({ electrical: options.electrical }), { seconds: Number(options.seconds) })
16 const { trace, path, ...report } = result
17 const transitionEvidence = trace.rows.flatMap(row => row.observation.transition?.outcome === 'confirmed' ? [row.observation.transition] : [])
18 const completeTransitions = transitionEvidence.length === 3 && transitionEvidence.every((row, index) => row.taskId === ['initial-hover', 'front', 'back'][index] && row.phase === ['hover', 'cruise', 'hover'][index])
19 const observedFlight = path.some(row => row.positionM && row.positionM[2] < -1 && row.actuators.slice(0, 4).some(n => n > 0))
20 const landingContact = path.at(-1)?.measurement?.values.onSurface === true
21 const boardNeutral = result.board.actuators.every(n => n === 0) && result.board.expiresAtMs === null
22 const demonstrationMatched = result.status === 'completed' && result.fault === null && result.mission.taskId === 'land' && result.mission.reason === 'landed' && completeTransitions && observedFlight && landingContact && boardNeutral
23 print(JSON.stringify({ ...report, scope: 'development-lift-and-cruise', transitionEvidence, completeTransitions, observedFlight, landingContact, boardNeutral, demonstrationMatched, recordedMissionRows: trace.rows.length, evaluatedPathRows: path.length }, (_key, value) => typeof value === 'bigint' ? String(value) : value, 2))
24 if (!demonstrationMatched) process.exitCode = 1
25 }
26 catch (error) { printError(error instanceof Error ? error.message : String(error)); process.exitCode = 1 }
27 },
28})