From fd9ca51a0586c5a3c0a73074d7a63f3babdb2cd0 Mon Sep 17 00:00:00 2001 From: Ray Morris Date: Sun, 21 Dec 2025 16:53:41 -0600 Subject: [PATCH] Docs: Add new JavaScript features (PID, flight modes, let/const, ternary) Adds documentation for new INAV 9.0 JavaScript programming features: New Features: - PID controller output access (inav.pid[0-3].output) - Flight mode detection (inav.flight.mode.poshold, .rth, etc.) - Let/const variables for compile-time named expressions - Ternary operator for conditional value assignment Changes: - Add Variables section with let/const and ternary operator docs - Update Available Objects to list PID and flight modes - Add Flight Mode Detection subsection with examples - Add PID Controller Outputs subsection with examples - Update index.md feature list - Update Tips section for consistency All examples use namespaced syntax (inav.flight.*, inav.override.*, etc.) for clarity and explicitness. --- .../JAVASCRIPT_PROGRAMMING_GUIDE.md | 97 ++++++++++++++++--- docs/javascript_programming/index.md | 9 +- 2 files changed, 91 insertions(+), 15 deletions(-) diff --git a/docs/javascript_programming/JAVASCRIPT_PROGRAMMING_GUIDE.md b/docs/javascript_programming/JAVASCRIPT_PROGRAMMING_GUIDE.md index 9c7dad4a8a9..fedda8bb7ac 100644 --- a/docs/javascript_programming/JAVASCRIPT_PROGRAMMING_GUIDE.md +++ b/docs/javascript_programming/JAVASCRIPT_PROGRAMMING_GUIDE.md @@ -198,28 +198,101 @@ inav.events.sticky( --- +## Variables + +### Let/Const Variables + +Use `let` or `const` to define reusable expressions that are compiled into the logic: + +```javascript +// Define reusable calculations +let distanceThreshold = 500; +let altitudeLimit = 100; +let combinedCondition = inav.flight.homeDistance > distanceThreshold && inav.flight.altitude > altitudeLimit; + +// Use in conditions +if (combinedCondition) { + inav.override.vtx.power = 4; +} +``` + +**Benefits:** +- Makes code more readable with named values +- Compiler automatically optimizes duplicate expressions +- Variables preserve their custom names through compile/decompile cycles + +**Important:** `let`/`const` variables are **compile-time substituted**, not runtime variables. For runtime state, use `inav.gvar[]`. + +### Ternary Operator + +Use ternary expressions for conditional values: + +```javascript +// Assign based on condition +let throttleLimit = inav.flight.cellVoltage < 330 ? 25 : 50; + +if (inav.flight.cellVoltage < 350) { + inav.override.throttleScale = throttleLimit; +} + +// Inline in expressions +inav.override.vtx.power = inav.flight.homeDistance > 500 ? 4 : 2; +``` + +**Use when:** You need conditional value assignment in a single expression. + +--- + ## Available Objects +The `inav` namespace provides access to all flight controller data and control functions: + +- `inav.flight` - Flight telemetry (including `flight.mode.*`) +- `inav.override` - Override flight parameters +- `inav.rc` - RC channels +- `inav.gvar` - Global variables (0-7) +- `inav.pid` - Programming PID outputs (`pid[0-3].output`) +- `inav.waypoint` - Waypoint navigation +- `inav.events.edge` - Edge detection +- `inav.events.sticky` - Latching conditions +- `inav.events.delay` - Delayed execution + +### Flight Mode Detection + +Check which flight modes are currently active via `inav.flight.mode.*`: + +```javascript +if (inav.flight.mode.poshold === 1) { + inav.gvar[0] = 1; // Flag: in position hold +} + +if (inav.flight.mode.rth === 1) { + inav.override.vtx.power = 4; // Max power during RTH +} +``` + +**Available modes:** `failsafe`, `manual`, `rth`, `poshold`, `cruise`, `althold`, `angle`, `horizon`, `air`, `acro`, `courseHold`, `waypointMission`, `user1` through `user4` + +### PID Controller Outputs + +Read output values from the 4 programming PID controllers (configured in Programming PID tab): + ```javascript -const { - flight, // Flight telemetry - override, // Override flight parameters - rc, // RC channels - gvar, // Global variables (0-7) - waypoint, // Waypoint navigation - edge, // Edge detection - sticky, // Latching conditions - delay // Delayed execution -} = inav; +if (inav.pid[0].output > 500) { + inav.override.throttle = 1600; +} +inav.gvar[0] = inav.pid[0].output; // Store for OSD display ``` +**Available:** `inav.pid[0].output` through `inav.pid[3].output` + --- ## Tips -1. **Initialize variables on arm** using `edge()` with `flight.armTimer > 1000` -2. **Use gvars for state** - they persist between logic condition evaluations +1. **Initialize variables on arm** using `inav.events.edge()` with `inav.flight.armTimer > 1000` +2. **Use inav.gvar for state** - they persist between logic condition evaluations 3. **edge() duration = 0** means instant trigger on condition becoming true 4. **edge() duration > 0** adds debounce time 5. **if statements are continuous** - they execute every cycle diff --git a/docs/javascript_programming/index.md b/docs/javascript_programming/index.md index 03f0f17fa0b..ce8ad26dd27 100644 --- a/docs/javascript_programming/index.md +++ b/docs/javascript_programming/index.md @@ -178,15 +178,18 @@ Instructions for: - Waypoint navigation **JavaScript Features:** -- `const` destructuring: `const { flight, override } = inav;` -- `let` variables: compile-time constant substitution +- Namespaced API access: `inav.flight.*`, `inav.override.*`, `inav.events.*` +- `let`/`const` variables: compile-time constant substitution - `var` variables: allocated to global variables +- Ternary operator: `condition ? value1 : value2` - Arrow functions: `() => condition` -- Object property access: `flight.altitude`, `rc[0].value` +- Object property access: `inav.flight.altitude`, `inav.rc[0].value` - Binary expressions: `+`, `-`, `*`, `/`, `%` - Comparison operators: `>`, `<`, `===` - Logical operators: `&&`, `||`, `!` - Math methods: `Math.min()`, `Math.max()`, `Math.sin()`, etc. +- Flight mode detection: `inav.flight.mode.poshold`, `inav.flight.mode.rth`, etc. +- PID controller outputs: `inav.pid[0-3].output` ### Validation