How Can We Help?
INAV Programming Framework
Framework
INAV Programming Framework (IPF) is a mechanism that allows you to to create custom functionality in INAV. You can choose for certain actions to be done, based on custom conditions you select.
Logic conditions can be based on things such as RC channel values, switches, altitude, distance, timers, etc. The conditions you create can also make use of other conditions you’ve entered previously. The results can be used in:
- Servo mixer to activate/deactivate certain servo mix rulers
- To activate/deactivate system overrides
INAV Programming Framework consists of:
- Logic Conditions – each Logic Condition can be understood as a single command, a single line of code. Each logic condition consists of:
- an operator (action), such as “plus” or “set vtx power”
- one or two operands (nouns), which the action acts upon. Operands are often numbers, such as a channel value or the distance to home.
- “activator” condition – optional. This condition is only active when another condition is true
 
- Global Variables – variables that can store values from and for Logic Conditions and servo mixer
- Programming PID – general purpose, user configurable PID controllers
IPF can be edited using INAV Configurator user interface, or via CLI. To use COnfigurator, click the tab labeled “Programming”. The various options shown in Configurator are described below.
Logic Conditions
CLI
logic <rule> <enabled> <activatorId> <operation> <operand A type> <operand A value> <operand B type> <operand B value> <flags>
- <rule>– ID of Logic Condition rule
- <enabled>–- 0evaluates as disabled,- 1evaluates as enabled
- <activatorId>– the ID of LogicCondition used to activate this Condition. Logic Condition will be evaluated only then Activator evaluates as- true.- -1evaluates as- true
- <operation>– See- Operationsparagraph
- <operand A type>– See- Operandsparagraph
- <operand A value>– See- Operandsparagraph
- <operand B type>– See- Operandsparagraph
- <operand B value>– See- Operandsparagraph
- <flags>– See- Flagsparagraph
Operations
| Operation ID | Name | Notes | 
|---|---|---|
| 0 | TRUE | Always evaluates as true | 
| 1 | EQUAL | Evaluates falseiffalseor0 | 
| 2 | GREATER_THAN | trueifOperand Ais a higher value thanOperand B | 
| 3 | LOWER_THAN | trueifOperand Ais a lower value thanOperand B | 
| 4 | LOW | trueif<1333 | 
| 5 | MID | trueif>=1333 and <=1666 | 
| 6 | HIGH | trueif>1666 | 
| 7 | AND | trueifOperand AandOperand Bare the same value or bothtrue | 
| 8 | OR | trueifOperand Aand/orOperandBistrue | 
| 9 | XOR | trueifOperand AorOperand Bistrue, but not both | 
| 10 | NAND | falseifOperand AandOperand Bare bothtrue | 
| 11 | NOR | trueifOperand AandOperand Bare bothfalse | 
| 12 | NOT | The boolean opposite to Operand A | 
| 13 | Sticky | Operand Ais the activation operator,Operand Bis the deactivation operator. After the activation istrue, the operator will returntrueuntil Operand B is evaluated astrue | 
| 14 | Basic: Add | Add Operand AtoOperand Band returns the result | 
| 15 | Basic: Subtract | Substract Operand BfromOperand Aand returns the result | 
| 16 | Basic: Multiply | Multiply Operand AbyOperand Band returns the result | 
| 17 | Basic: Divide | Divide Operand AbyOperand Band returns the result | 
| 18 | Set GVAR | Store value from Operand Binto the Global Variable addressed by | 
| Operand A. Bear in mind, that operandGlobal Variablemeans: Value stored in Global Variable of an index! To store in GVAR 1 useValue 1notGlobal Variable 1 | ||
| 19 | Increase GVAR | Increase the GVAR indexed by Operand A(useValue 1for Global Variable 1) with value fromOperand B | 
| 20 | Decrease GVAR | Decrease the GVAR indexed by Operand A(useValue 1for Global Variable 1) with value fromOperand B | 
| 21 | Set IO Port | Set I2C IO Expander pin Operand Ato value ofOperand B.Operand Aaccepts values0-7andOperand Baccepts0and1 | 
| 22 | OVERRIDE_ARMING_SAFETY | Allows the craft to arm on any angle even without GPS fix. WARNING: This bypasses all safety checks, even that the throttle is low, so use with caution. If you only want to check for certain conditions, such as arm without GPS fix. You will need to add logic conditions to check the throttle is low. | 
| 23 | OVERRIDE_THROTTLE_SCALE | Override throttle scale to the value defined by operand. Operand type 0and value50means throttle will be scaled by 50%. | 
| 24 | SWAP_ROLL_YAW | basically, when activated, yaw stick will control roll and roll stick will control yaw. Required for tail-sitters VTOL during vertical-horizonral transition when body frame changes | 
| 25 | SET_VTX_POWER_LEVEL | Sets VTX power level. Accepted values are 0-3for SmartAudio and0-4for Tramp protocol | 
| 26 | INVERT_ROLL | Inverts ROLL axis input for PID/PIFF controller | 
| 27 | INVERT_PITCH | Inverts PITCH axis input for PID/PIFF controller | 
| 28 | INVERT_YAW | Inverts YAW axis input for PID/PIFF controller | 
| 29 | OVERRIDE_THROTTLE | Override throttle value that is fed to the motors by mixer. Operand is scaled in us. 1000means throttle cut,1500means half throttle | 
| 30 | SET_VTX_BAND | Sets VTX band. Accepted values are 1-5 | 
| 31 | SET_VTX_CHANNEL | Sets VTX channel. Accepted values are 1-8 | 
| 32 | SET_OSD_LAYOUT | Sets OSD layout. Accepted values are 0-3 | 
| 33 | Trigonometry: Sine | Computes SIN of Operand Avalue in degrees. Output is multiplied byOperand Bvalue. IfOperand Bis0, result is multiplied by500 | 
| 34 | Trigonometry: Cosine | Computes COS of Operand Avalue in degrees. Output is multiplied byOperand Bvalue. IfOperand Bis0, result is multiplied by500 | 
| 35 | Trigonometry: Tangent | Computes TAN of Operand Avalue in degrees. Output is multiplied byOperand Bvalue. IfOperand Bis0, result is multiplied by500 | 
| 36 | MAP_INPUT | Scales Operand Afrom [0:Operand B] to [0:1000]. Note: input will be constrained and then scaled | 
| 37 | MAP_OUTPUT | Scales Operand Afrom [0:1000] to [0:Operand B]. Note: input will be constrained and then scaled | 
| 38 | RC_CHANNEL_OVERRIDE | Overrides channel set by Operand Ato value ofOperand B. Note operand A should normally be set as a “Value”, NOT as “Get RC Channel” | 
| 39 | SET_HEADING_TARGET | Sets heading-hold target to Operand A, in degrees. Value wraps-around. | 
| 40 | Modulo | Modulo. Divide Operand AbyOperand Band returns the remainder | 
| 41 | LOITER_RADIUS_OVERRIDE | Sets the loiter radius to Operand A[0:100000] in cm. If the value is lower than the loiter radius set in the Advanced Tuning, that will be used. | 
| 42 | SET_PROFILE | Sets the active config profile (PIDFF/Rates/Filters/etc) to Operand A.Operand Amust be a valid profile number, currently from 1 to 3. If not, the profile will not change | 
| 43 | Use Lowest Value | Finds the lowest value of Operand AandOperand B | 
| 44 | Use Highest Value | Finds the highest value of Operand AandOperand B | 
| 45 | FLIGHT_AXIS_ANGLE_OVERRIDE | Sets the target attitude angle for axis. In other words, when active, it enforces Angle mode (Heading Hold for Yaw) on this axis (Angle mode does not have to be active). Operand Adefines the axis:0– Roll,1– Pitch,2– Yaw.Operand Bdefines the angle in degrees | 
| 46 | FLIGHT_AXIS_RATE_OVERRIDE | Sets the target rate (rotation speed) for axis. Operand Adefines the axis:0– Roll,1– Pitch,2– Yaw.Operand Bdefines the rate in degrees per second | 
| 47 | EDGE | Momentarily true when triggered by Operand A.Operand Ais the activation operator [boolean],Operand B(Optional) is the time for the edge to stay active [ms]. After activation, operator will returntrueuntil the time in Operand B is reached. If a pure momentary edge is wanted. Just leaveOperand Bas the defaultValue: 0setting. | 
| 48 | DELAY | Delays activation after being triggered. This will return truewhenOperand Ais true, and the delay time inOperand B[ms] has been exceeded. | 
| 49 | TIMER | A simple on – off timer. truefor the duration ofOperand A[ms]. Thenfalsefor the duration ofOperand B[ms]. | 
| 50 | DELTA | This returns truewhen the value ofOperand Ahas changed by the value ofOperand Bor greater within 100ms. | 
| 51 | APPROX_EQUAL | trueifOperand Bis within 1% ofOperand A. | 
| 52 | LED_PIN_PWM | Value Operand Afrom [0:100] starts PWM generation on LED Pin. See LED pin PWM. Any other value stops PWM generation (stop to allow ws2812 LEDs updates in shared modes) | 
Operands
| Operand Type | Name | Notes | 
|---|---|---|
| 0 | VALUE | Value derived from valuefield | 
| 1 | GET_RC_CHANNEL | valuepoints to RC channel number, indexed from 1 | 
| 2 | FLIGHT | valuepoints to flight parameter table | 
| 3 | FLIGHT_MODE | valuepoints to flight modes table | 
| 4 | LC | valuepoints to other logic condition ID | 
| 5 | GVAR | Value stored in Global Variable indexed by value.GVAR 1means: value in GVAR 1 | 
| 5 | PID | Output of a Programming PID indexed by value.PID 1means: value in PID 1 | 
FLIGHT
| Operand Value | Name | Notes | 
|---|---|---|
| 0 | ARM_TIMER | in seconds | 
| 1 | HOME_DISTANCE | in meters | 
| 2 | TRIP_DISTANCE | in meters | 
| 3 | RSSI | |
| 4 | VBAT | in Volts * 100, eg.12.1Vis1210 | 
| 5 | CELL_VOLTAGE | in Volts * 100, eg.12.1Vis1210 | 
| 6 | CURRENT | in Amps * 100, eg.9Ais900 | 
| 7 | MAH_DRAWN | in mAh | 
| 8 | GPS_SATS | |
| 9 | GROUD_SPEED | in cm/s | 
| 10 | 3D_SPEED | in cm/s | 
| 11 | AIR_SPEED | in cm/s | 
| 12 | ALTITUDE | in cm | 
| 13 | VERTICAL_SPEED | in cm/s | 
| 14 | TROTTLE_POS | in % | 
| 15 | ATTITUDE_ROLL | in degrees | 
| 16 | ATTITUDE_PITCH | in degrees | 
| 17 | IS_ARMED | boolean 0/1 | 
| 18 | IS_AUTOLAUNCH | boolean 0/1 | 
| 19 | IS_ALTITUDE_CONTROL | boolean 0/1 | 
| 20 | IS_POSITION_CONTROL | boolean 0/1 | 
| 21 | IS_EMERGENCY_LANDING | boolean 0/1 | 
| 22 | IS_RTH | boolean 0/1 | 
| 23 | IS_LANDING | boolean 0/1 | 
| 24 | IS_FAILSAFE | boolean 0/1 | 
| 25 | STABILIZED_ROLL | Roll PID controller output [-500:500] | 
| 26 | STABILIZED_PITCH | Pitch PID controller output [-500:500] | 
| 27 | STABILIZED_YAW | Yaw PID controller output [-500:500] | 
| 28 | 3D HOME_DISTANCE | in meters, calculated from HOME_DISTANCE and ALTITUDE using Pythagorean theorem | 
| 29 | CROSSFIRE LQ | Crossfire Link quality as returned by the CRSF protocol | 
| 30 | CROSSFIRE SNR | Crossfire SNR as returned by the CRSF protocol | 
| 31 | GPS_VALID | boolean 0/1. True when the GPS has a valid 3D Fix | 
| 32 | LOITER_RADIUS | The current loiter radius in cm. | 
| 33 | ACTIVE_PROFILE | integer for the active config profile [1..MAX_PROFILE_COUNT] | 
| 34 | BATT_CELLS | Number of battery cells detected | 
| 35 | AGL_STATUS | boolean 1when AGL can be trusted,0when AGL estimate can not be trusted | 
| 36 | AGL | integer Above The Groud Altitude in cm | 
| 37 | RANGEFINDER_RAW | integer raw distance provided by the rangefinder in cm | 
| 38 | ACTIVE_MIXER_PROFILE | Which mixers are currently active (for vtol etc) | 
| 39 | MIXER_TRANSITION_ACTIVE | Currently switching between mixers (quad to plane etc) | 
| 40 | ATTITUDE_YAW | current heading (yaw) in degrees | 
| 41 | FW Land Sate | integer 1–5, indicates the status of the FW landing, 0 Idle, 1 Downwind, 2 Base Leg, 3 Final Approach, 4 Glide, 5 Flare | 
FLIGHT_MODE
The flight mode operands return true when the mode is active. These are modes that you will see in the Modes tab. Note: the USER* modes are used by camera switchers, PINIO etc. They are not the Waypoint User Actions. See the Waypoints section to access those.
| Operand Value | Name | Notes | 
|---|---|---|
| 0 | FAILSAFE | truewhen a Failsafe state has been triggered. | 
| 1 | MANUAL | truewhen you are in the Manual flight mode. | 
| 2 | RTH | truewhen you are in the Return to Home flight mode. | 
| 3 | POSHOLD | truewhen you are in the Position Hold or Loiter flight modes. | 
| 4 | CRUISE | truewhen you are in the Cruise flight mode. | 
| 5 | ALTHOLD | truewhen you the Altitude Hold flight mode modifier is active. | 
| 6 | ANGLE | truewhen you are in the Angle flight mode. | 
| 7 | HORIZON | truewhen you are in the Horizon flight mode. | 
| 8 | AIR | truewhen you the Airmode flight mode modifier is active. | 
| 9 | USER1 | truewhen the USER 1 mode is active. | 
| 10 | USER2 | truewhen the USER 2 mode is active. | 
| 11 | COURSE_HOLD | truewhen you are in the Course Hold flight mode. | 
| 12 | USER3 | truewhen the USER 3 mode is active. | 
| 13 | USER4 | truewhen the USER 4 mode is active. | 
| 14 | ACRO | truewhen you are in the Acro flight mode. | 
| 15 | WAYPOINT_MISSION | truewhen you are in the WP Mission flight mode. | 
WAYPOINTS
| Operand Value | Name | Notes | 
|---|---|---|
| 0 | Is WP | Boolean 0/1 | 
| 1 | Current Waypoint Index | Current waypoint leg. Indexed from 1. To verify WP is in progress, useIs WP | 
| 2 | Current Waypoint Action | truewhen Action active in current leg. See ACTIVE_WAYPOINT_ACTION table | 
| 3 | Next Waypoint Action | truewhen Action active in next leg. See ACTIVE_WAYPOINT_ACTION table | 
| 4 | Distance to next Waypoint | Distance to next WP in metres | 
| 5 | Distance from Waypoint | Distance from the last WP in metres | 
| 6 | User Action 1 | truewhen User Action 1 is active on this waypoint leg [boolean0/1] | 
| 7 | User Action 2 | truewhen User Action 2 is active on this waypoint leg [boolean0/1] | 
| 8 | User Action 3 | truewhen User Action 3 is active on this waypoint leg [boolean0/1] | 
| 9 | User Action 4 | truewhen User Action 4 is active on this waypoint leg [boolean0/1] | 
| 10 | Next Waypoint User Action 1 | truewhen User Action 1 is active on the next waypoint leg [boolean0/1] | 
| 11 | Next Waypoint User Action 2 | truewhen User Action 2 is active on the next waypoint leg [boolean0/1] | 
| 12 | Next Waypoint User Action 3 | truewhen User Action 3 is active on the next waypoint leg [boolean0/1] | 
| 13 | Next Waypoint User Action 4 | truewhen User Action 4 is active on the next waypoint leg [boolean0/1] | 
ACTIVE_WAYPOINT_ACTION
| Action | Value | 
|---|---|
| WAYPOINT | 1 | 
| HOLD_TIME | 3 | 
| RTH | 4 | 
| SET_POI | 5 | 
| JUMP | 6 | 
| SET_HEAD | 7 | 
| LAND | 8 | 
Flags
All flags are reseted on ARM and DISARM event.
| bit | Decimal | Function | 
|---|---|---|
| 0 | 1 | Latch – after activation LC will stay active until LATCH flag is reset | 
| 1 | 2 | Timeout satisfied – Used in timed operands to determine if the timeout has been met | 
Global variables
CLI
gvar <index> <default value> <min> <max>
Programming PID
pid <index> <enabled> <setpoint type> <setpoint value> <measurement type> <measurement value> <P gain> <I gain> <D gain> <FF gain>
- <index>– ID of PID Controller, starting from- 0
- <enabled>–- 0evaluates as disabled,- 1evaluates as enabled
- <setpoint type>– See- Operandsparagraph
- <setpoint value>– See- Operandsparagraph
- <measurement type>– See- Operandsparagraph
- <measurement value>– See- Operandsparagraph
- <P gain>– P-gain, scaled to- 1/1000
- <I gain>– I-gain, scaled to- 1/1000
- <D gain>– D-gain, scaled to- 1/1000
- <FF gain>– FF-gain, scaled to- 1/1000
Examples- Programming Tab
When more than 100 meters away, increase VTX power

When more than 600 meters away, engage return-to-home by setting the matching RC channel

Dynamic THROTTLE scale
logic 0 1 0 23 0 50 0 0 0
Limits the THROTTLE output to 50% when Logic Condition 0 evaluates as true
Set VTX power level via Smart Audio
logic 0 1 0 25 0 3 0 0 0
Sets VTX power level to 3 when Logic Condition 0 evaluates as true
Invert ROLL and PITCH when rear facing camera FPV is used
Solves the problem from #4439
logic 0 1 0 26 0 0 0 0 0
logic 1 1 0 27 0 0 0 0 0
Inverts ROLL and PITCH input when Logic Condition 0 evaluates as true. Moving Pitch stick up will cause pitch down (up for rear facing camera). Moving Roll stick right will cause roll left of a quad (right in rear facing camera)
Cut motors but keep other throttle bindings active
logic 0 1 0 29 0 1000 0 0 0
Sets throttle output to 0% when Logic Condition 0 evaluates as true
Set throttle to 50% and keep other throttle bindings active
logic 0 1 0 29 0 1500 0 0 0
Sets throttle output to about 50% when Logic Condition 0 evaluates as true
Set throttle control to different RC channel
logic 0 1 0 29 1 7 0 0 0
If Logic Condition 0 evaluates as true, motor throttle control is bound to RC channel 7 instead of throttle channel
Set VTX channel with a POT
Set VTX channel with a POT on the radio assigned to RC channel 6
logic 0 1 -1 15 1 6 0 1000 0
logic 1 1 -1 37 4 0 0 7 0
logic 2 1 -1 14 4 1 0 1 0
logic 3 1 -1 31 4 2 0 0 0
Steps:
- Normalize range [1000:2000]to[0:1000]by substracting1000
- Scale range [0:1000]to[0:7]
- Increase range by 1to have the range of[1:8]
- Assign LC#2 to VTX channel function
Set VTX power with a POT
Set VTX power with a POT on the radio assigned to RC channel 6. In this example we scale POT to 4 power level [1:4]
logic 0 1 -1 15 1 6 0 1000 0
logic 1 1 -1 37 4 0 0 3 0
logic 2 1 -1 14 4 1 0 1 0
logic 3 1 -1 25 4 2 0 0 0
Steps:
- Normalize range [1000:2000] to [0:1000] by substracting 1000
- Scale range [0:1000] to [0:3]
- Increase range by 1to have the range of [1:4]
- Assign LC#2 to VTX power function
Common issues / questions about IPF
One common mistake involves setting RC channel values. To override (set) the value of a specific RC channel, choose “Override RC value”, then for operand A choose value and enter the channel number. Choosing “get RC value” is a common mistake, which does something other than what you probably want.

