LCOV - code coverage report
Current view: top level - home/pbarker/rc/ardupilot/ArduSub - Parameters.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 61 90 67.8 %
Date: 2026-09-09 11:02:08 Functions: 6 7 85.7 %

          Line data    Source code
       1             : #include "Sub.h"
       2             : 
       3             : #include <AP_Gripper/AP_Gripper.h>
       4             : 
       5             : /*
       6             :    This program is free software: you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation, either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : /*
      21             :  *  ArduSub parameter definitions
      22             :  *
      23             :  */
      24             : 
      25             : const AP_Param::Info Sub::var_info[] = {
      26             : 
      27             :     // @Param: SURFACE_DEPTH
      28             :     // @DisplayName: Depth reading at surface
      29             :     // @Description: The depth the external pressure sensor will read when the vehicle is considered at the surface (in centimeters)
      30             :     // @Units: cm
      31             :     // @Range: -100 0
      32             :     // @User: Standard
      33             :     GSCALAR(surface_depth, "SURFACE_DEPTH", SURFACE_DEPTH_DEFAULT),
      34             : 
      35             :     // @Param: FORMAT_VERSION
      36             :     // @DisplayName: Eeprom format version number
      37             :     // @Description: This value is incremented when changes are made to the eeprom format
      38             :     // @User: Advanced
      39             :     GSCALAR(format_version, "FORMAT_VERSION",   0),
      40             : 
      41             :     // SYSID_THISMAV was here
      42             : 
      43             :     // SYSID_MYGCS was here
      44             : 
      45             :     // @Param: PILOT_THR_FILT
      46             :     // @DisplayName: Throttle filter cutoff
      47             :     // @Description: Throttle filter cutoff (Hz) - active whenever altitude control is inactive - 0 to disable
      48             :     // @User: Advanced
      49             :     // @Units: Hz
      50             :     // @Range: 0 10
      51             :     // @Increment: 0.5
      52             :     GSCALAR(throttle_filt,  "PILOT_THR_FILT",     0),
      53             : 
      54             :     // AP_SerialManager was here
      55             : 
      56             :     // @Param: GCS_PID_MASK
      57             :     // @DisplayName: GCS PID tuning mask
      58             :     // @Description: bitmask of PIDs to send MAVLink PID_TUNING messages for
      59             :     // @User: Advanced
      60             :     // @Bitmask: 0:Roll,1:Pitch,2:Yaw
      61             :     GSCALAR(gcs_pid_mask,           "GCS_PID_MASK",     0),
      62             : 
      63             :     // @Param: FS_GCS_ENABLE
      64             :     // @DisplayName: Ground Station Failsafe Enable
      65             :     // @Description: Controls what action to take when GCS heartbeat is lost.
      66             :     // @Values: 0:Disabled,1:Warn only,2:Disarm,3:Enter depth hold mode,4:Enter surface mode
      67             :     // @User: Standard
      68             :     GSCALAR(failsafe_gcs, "FS_GCS_ENABLE", FS_GCS_DISARM),
      69             : 
      70             :     // @Param: FS_GCS_TIMEOUT
      71             :     // @DisplayName: GCS failsafe timeout
      72             :     // @Description: Timeout before triggering the GCS failsafe
      73             :     // @Units: s
      74             :     // @Increment: 1
      75             :     // @User: Standard
      76             :     GSCALAR(failsafe_gcs_timeout, "FS_GCS_TIMEOUT", FS_GCS_TIMEOUT_S),
      77             : 
      78             :     // @Param: FS_LEAK_ENABLE
      79             :     // @DisplayName: Leak Failsafe Enable
      80             :     // @Description: Controls what action to take if a leak is detected.
      81             :     // @Values: 0:Disabled,1:Warn only,2:Enter surface mode
      82             :     // @User: Standard
      83             :     GSCALAR(failsafe_leak, "FS_LEAK_ENABLE", FS_LEAK_WARN_ONLY),
      84             : 
      85             :     // @Param: FS_PRESS_ENABLE
      86             :     // @DisplayName: Internal Pressure Failsafe Enable
      87             :     // @Description: Controls what action to take if internal pressure exceeds FS_PRESS_MAX parameter.
      88             :     // @Values: 0:Disabled,1:Warn only
      89             :     // @User: Standard
      90             :     GSCALAR(failsafe_pressure, "FS_PRESS_ENABLE", FS_PRESS_DISABLED),
      91             : 
      92             :     // @Param: FS_TEMP_ENABLE
      93             :     // @DisplayName: Internal Temperature Failsafe Enable
      94             :     // @Description: Controls what action to take if internal temperature exceeds FS_TEMP_MAX parameter.
      95             :     // @Values: 0:Disabled,1:Warn only
      96             :     // @User: Standard
      97             :     GSCALAR(failsafe_temperature, "FS_TEMP_ENABLE", FS_TEMP_DISABLED),
      98             :     
      99             : #if AP_SUB_RC_ENABLED        
     100             :     // @Param: FS_THR_ENABLE
     101             :     // @DisplayName: Throttle Failsafe Enable
     102             :     // @Description: The throttle failsafe allows you to configure a software RC failsafe activated by a setting on the throttle input channel. It also enables RC failsafe on absence of RC signals being recieved.
     103             :     // @Values:  0:Disabled,1: Force effective control inputs to trim positions and prevent arming,2:Surface and hold on surface on failsafe 
     104             :     // @User: Standard
     105             :     GSCALAR(failsafe_throttle,  "FS_THR_ENABLE",   0),
     106             : 
     107             :     // @Param: FS_THR_VALUE
     108             :     // @DisplayName: Throttle Failsafe Value
     109             :     // @Description: The PWM level in microseconds on channel 3 below which throttle failsafe triggers
     110             :     // @Range: 910 1100
     111             :     // @Units: PWM
     112             :     // @Increment: 1
     113             :     // @User: Standard
     114             :     GSCALAR(failsafe_throttle_value, "FS_THR_VALUE",  FS_THR_VALUE_DEFAULT),
     115             :     
     116             :     // @Param: FLTMODE1
     117             :     // @DisplayName: Flight Mode 1
     118             :     // @Description: Flight mode when pwm of Flightmode channel(FLTMODE_CH) is <= 1230
     119             :     // @Values: 0:Stabilize,1:Acro,2:AltHold,3:Auto,4:Guided,7:Circle,9:Surface,16:PosHold,19:Manual,20:Motor Detect,21:SurfTrak
     120             :     // @User: Standard
     121             :     GARRAY(flight_modes, 0, "FLTMODE1", (uint8_t)FLIGHT_MODE_1),
     122             : 
     123             :     // @Param: FLTMODE2
     124             :     // @CopyFieldsFrom: FLTMODE1
     125             :     // @DisplayName: Flight Mode 2
     126             :     // @Description: Flight mode when pwm of Flightmode channel(FLTMODE_CH) is >1230, <= 1360
     127             :     GARRAY(flight_modes, 1, "FLTMODE2", (uint8_t)FLIGHT_MODE_2),
     128             : 
     129             :     // @Param: FLTMODE3
     130             :     // @CopyFieldsFrom: FLTMODE1
     131             :     // @DisplayName: Flight Mode 3
     132             :     // @Description: Flight mode when pwm of Flightmode channel(FLTMODE_CH) is >1360, <= 1490
     133             :     GARRAY(flight_modes, 2, "FLTMODE3", (uint8_t)FLIGHT_MODE_3),
     134             : 
     135             :     // @Param: FLTMODE4
     136             :     // @CopyFieldsFrom: FLTMODE1
     137             :     // @DisplayName: Flight Mode 4
     138             :     // @Description: Flight mode when pwm of Flightmode channel(FLTMODE_CH) is >1490, <= 1620
     139             :     GARRAY(flight_modes, 3, "FLTMODE4", (uint8_t)FLIGHT_MODE_4),
     140             : 
     141             :     // @Param: FLTMODE5
     142             :     // @CopyFieldsFrom: FLTMODE1
     143             :     // @DisplayName: Flight Mode 5
     144             :     // @Description: Flight mode when pwm of Flightmode channel(FLTMODE_CH) is >1620, <= 1749
     145             :     GARRAY(flight_modes, 4, "FLTMODE5", (uint8_t)FLIGHT_MODE_5),
     146             : 
     147             :     // @Param: FLTMODE6
     148             :     // @CopyFieldsFrom: FLTMODE1
     149             :     // @DisplayName: Flight Mode 6
     150             :     // @Description: Flight mode when pwm of Flightmode channel(FLTMODE_CH) is >=1750
     151             :     GARRAY(flight_modes, 5, "FLTMODE6", (uint8_t)FLIGHT_MODE_6),
     152             : 
     153             :     // @Param: FLTMODE_CH
     154             :     // @DisplayName: Flightmode channel
     155             :     // @Description: RC Channel to use for flight mode control
     156             :     // @Values: 0:Disabled,5:Channel5,6:Channel6,7:Channel7,8:Channel8,9:Channel9,10:Channel 10,11:Channel 11,12:Channel 12,13:Channel 13,14:Channel 14,15:Channel 15
     157             :     // @User: Advanced
     158             :     GSCALAR(flight_mode_chan, "FLTMODE_CH",         0),
     159             : 
     160             :     // @Param: THR_ARM_POS
     161             :     // @DisplayName: Throttle arming position
     162             :     // @Description: Determines if throttle must be at min or within trim value to arm, if RC checks and RC_OPTION for "0" throttle are enabled.
     163             :     // @User: Standard
     164             :     // @Bitmask: 0:Throttle at or below min, 1: Throttle within a dead zone of RC trim value
     165             :     GSCALAR(thr_arming_position, "THR_ARM_POS", 1),    
     166             : #endif
     167             :     // @Param: FS_PRESS_MAX
     168             :     // @DisplayName: Internal Pressure Failsafe Threshold
     169             :     // @Description: The maximum internal pressure allowed before triggering failsafe. Failsafe action is determined by FS_PRESS_ENABLE parameter
     170             :     // @Units: Pa
     171             :     // @User: Standard
     172             :     GSCALAR(failsafe_pressure_max, "FS_PRESS_MAX", FS_PRESS_MAX_DEFAULT),
     173             : 
     174             :     // @Param: FS_TEMP_MAX
     175             :     // @DisplayName: Internal Temperature Failsafe Threshold
     176             :     // @Description: The maximum internal temperature allowed before triggering failsafe. Failsafe action is determined by FS_TEMP_ENABLE parameter.
     177             :     // @Units: degC
     178             :     // @User: Standard
     179             :     GSCALAR(failsafe_temperature_max, "FS_TEMP_MAX", FS_TEMP_MAX_DEFAULT),
     180             : 
     181             :     // @Param: SURFACE_MAX_THR
     182             :     // @DisplayName: Surface Maximum Throttle
     183             :     // @Description: Maximum throttle value when the vehicle is at the surface. This value is used to scale throttle linearly from 1. (full) to min as the vehicle approaches the surface. The attenuation starts at 1 meter from surface.  Only upwards throttle is limited.
     184             :     // @Range: 0.0 1.0
     185             :     // @User: Standard
     186             :     // @Increment: 0.01
     187             :     GSCALAR(surface_max_throttle, "SURFACE_MAX_THR", 0.1f),
     188             : 
     189             :     // @Param: FS_TERRAIN_ENAB
     190             :     // @DisplayName: Terrain Failsafe Enable
     191             :     // @Description: Controls what action to take if terrain information is lost during AUTO mode
     192             :     // @Values: 0:Disarm, 1:Hold Position, 2:Surface
     193             :     // @User: Standard
     194             :     GSCALAR(failsafe_terrain, "FS_TERRAIN_ENAB", FS_TERRAIN_DISARM),
     195             : 
     196             :     // @Param: FS_PILOT_INPUT
     197             :     // @DisplayName: Pilot input failsafe action
     198             :     // @Description: Controls what action to take if no pilot input has been received after the timeout period specified by the FS_PILOT_TIMEOUT parameter
     199             :     // @Values: 0:Disabled, 1:Warn Only, 2:Disarm
     200             :     // @User: Standard
     201             :     GSCALAR(failsafe_pilot_input, "FS_PILOT_INPUT", FS_PILOT_INPUT_DISARM),
     202             : 
     203             :     // @Param: FS_PILOT_TIMEOUT
     204             :     // @DisplayName: Timeout for activation of pilot input failsafe
     205             :     // @Description: Controls the maximum interval between received pilot inputs before the failsafe action is triggered
     206             :     // @Units: s
     207             :     // @Range: 0.1 3.0
     208             :     // @User: Standard
     209             :     GSCALAR(failsafe_pilot_input_timeout, "FS_PILOT_TIMEOUT", 3.0f),
     210             : 
     211             :     // @Param: XTRACK_ANG_LIM
     212             :     // @DisplayName: Crosstrack correction angle limit
     213             :     // @Description: Maximum allowed angle (in degrees) between current track and desired heading during waypoint navigation
     214             :     // @Range: 10 90
     215             :     // @User: Standard
     216             :     GSCALAR(xtrack_angle_limit,"XTRACK_ANG_LIM", 45),
     217             : 
     218             :     // @Param: WP_YAW_BEHAVIOR
     219             :     // @DisplayName: Yaw behaviour during missions
     220             :     // @Description: Determines how the autopilot controls the yaw during missions and RTL
     221             :     // @Values: 0:Never change yaw, 1:Face next waypoint, 2:Face next waypoint except RTL, 3:Face along GPS course, 4:Correct crosstrack error
     222             :     // @User: Standard
     223             :     GSCALAR(wp_yaw_behavior,  "WP_YAW_BEHAVIOR",    WP_YAW_BEHAVIOR_DEFAULT),
     224             : 
     225             :     // @Param: PILOT_SPEED_UP
     226             :     // @DisplayName: Pilot maximum vertical ascending speed
     227             :     // @Description: The maximum vertical ascending velocity the pilot may request in cm/s
     228             :     // @Units: cm/s
     229             :     // @Range: 20 500
     230             :     // @Increment: 10
     231             :     // @User: Standard
     232             :     GSCALAR(pilot_speed_up,     "PILOT_SPEED_UP",   PILOT_VELZ_MAX),
     233             : 
     234             :     // @Param: PILOT_SPEED_DN
     235             :     // @DisplayName: Pilot maximum vertical descending speed
     236             :     // @Description: The maximum vertical descending velocity the pilot may request in cm/s
     237             :     // @Units: cm/s
     238             :     // @Range: 20 500
     239             :     // @Increment: 10
     240             :     // @User: Standard
     241             :     GSCALAR(pilot_speed_dn,     "PILOT_SPEED_DN",   0),
     242             : 
     243             :     // @Param: PILOT_SPEED
     244             :     // @DisplayName: Pilot maximum horizontal speed
     245             :     // @Description: The maximum horizontal velocity the pilot may request in cm/s
     246             :     // @Units: cm/s
     247             :     // @Range: 10 500
     248             :     // @Increment: 10
     249             :     // @User: Standard
     250             :     GSCALAR(pilot_speed,     "PILOT_SPEED",   PILOT_SPEED_DEFAULT),
     251             : 
     252             :     // @Param: PILOT_ACCEL_Z
     253             :     // @DisplayName: Pilot vertical acceleration
     254             :     // @Description: The vertical acceleration used when pilot is controlling the altitude
     255             :     // @Units: cm/s/s
     256             :     // @Range: 50 500
     257             :     // @Increment: 10
     258             :     // @User: Standard
     259             :     GSCALAR(pilot_accel_z,  "PILOT_ACCEL_Z",    PILOT_ACCEL_Z_DEFAULT),
     260             : 
     261             :     // @Param: THR_DZ
     262             :     // @DisplayName: Throttle deadzone
     263             :     // @Description: The PWM deadzone in microseconds above and below mid throttle. Used in AltHold, Loiter, PosHold flight modes
     264             :     // @User: Standard
     265             :     // @Range: 0 300
     266             :     // @Units: PWM
     267             :     // @Increment: 1
     268             :     GSCALAR(throttle_deadzone,  "THR_DZ",    THR_DZ_DEFAULT),
     269             : 
     270             :     // @Param: LOG_BITMASK
     271             :     // @DisplayName: Log bitmask
     272             :     // @Description: 4 byte bitmap of log types to enable
     273             :     // @Bitmask: 0:ATTITUDE_FAST,1:ATTITUDE_MED,2:GPS,3:PM,4:CTUN,5:NTUN,6:RCIN,7:IMU,8:CMD,9:CURRENT,10:RCOUT,11:OPTFLOW,12:PID,13:COMPASS,14:INAV,15:CAMERA,17:MOTBATT,18:IMU_FAST,19:IMU_RAW
     274             :     // @User: Standard
     275             :     GSCALAR(log_bitmask,    "LOG_BITMASK",          DEFAULT_LOG_BITMASK),
     276             : 
     277             :     // @Param: FS_EKF_ACTION
     278             :     // @DisplayName: EKF Failsafe Action
     279             :     // @Description: Controls the action that will be taken when an EKF failsafe is invoked
     280             :     // @Values: 0:Disabled, 1:Warn only, 2:Disarm
     281             :     // @User: Advanced
     282             :     GSCALAR(fs_ekf_action, "FS_EKF_ACTION",    FS_EKF_ACTION_DEFAULT),
     283             : 
     284             :     // @Param: FS_EKF_THRESH
     285             :     // @DisplayName: EKF failsafe variance threshold
     286             :     // @Description: Allows setting the maximum acceptable compass and velocity variance
     287             :     // @Values: 0.6:Strict, 0.8:Default, 1.0:Relaxed
     288             :     // @Range: 0.6 1.0
     289             :     // @User: Advanced
     290             :     GSCALAR(fs_ekf_thresh, "FS_EKF_THRESH",    FS_EKF_THRESHOLD_DEFAULT),
     291             : 
     292             :     // @Param: FS_CRASH_CHECK
     293             :     // @DisplayName: Crash check enable
     294             :     // @Description: This enables automatic crash checking. When enabled the motors will disarm if a crash is detected.
     295             :     // @Values: 0:Disabled,1:Warn only,2:Disarm
     296             :     // @User: Advanced
     297             :     GSCALAR(fs_crash_check, "FS_CRASH_CHECK",    FS_CRASH_DISABLED),
     298             : 
     299             :     // @Param: JS_GAIN_DEFAULT
     300             :     // @DisplayName: Default gain at boot
     301             :     // @Description: Default gain at boot, must be in range [JS_GAIN_MIN , JS_GAIN_MAX]. Current gain value is accessible via NAMED_VALUE_FLOAT MAVLink message with name 'PilotGain'.
     302             :     // @User: Standard
     303             :     // @Range: 0.1 1.0
     304             :     GSCALAR(gain_default, "JS_GAIN_DEFAULT", 0.5),
     305             : 
     306             :     // @Param: JS_GAIN_MAX
     307             :     // @DisplayName: Maximum joystick gain
     308             :     // @Description: Maximum joystick gain
     309             :     // @User: Standard
     310             :     // @Range: 0.2 1.0
     311             :     GSCALAR(maxGain, "JS_GAIN_MAX", 1.0),
     312             : 
     313             :     // @Param: JS_GAIN_MIN
     314             :     // @DisplayName: Minimum joystick gain
     315             :     // @Description: Minimum joystick gain
     316             :     // @User: Standard
     317             :     // @Range: 0.1 0.8
     318             :     GSCALAR(minGain, "JS_GAIN_MIN", 0.25),
     319             : 
     320             :     // @Param: JS_GAIN_STEPS
     321             :     // @DisplayName: Gain steps
     322             :     // @Description: Controls the number of steps between minimum and maximum joystick gain when the gain is adjusted using buttons. Set to 1 to always use JS_GAIN_DEFAULT.
     323             :     // @User: Standard
     324             :     // @Range: 1 10
     325             :     GSCALAR(numGainSettings, "JS_GAIN_STEPS", 4),
     326             : 
     327             :     // @Param: JS_LIGHTS_STEPS
     328             :     // @DisplayName: Lights brightness steps
     329             :     // @Description: Number of steps in brightness between minimum and maximum brightness
     330             :     // @User: Standard
     331             :     // @Range: 1 10
     332             :     // @Units: PWM
     333             :     GSCALAR(lights_steps, "JS_LIGHTS_STEPS", 8),
     334             : 
     335             :     // @Param: JS_THR_GAIN
     336             :     // @DisplayName: Throttle gain scalar
     337             :     // @Description: Scalar for gain on the throttle channel. Gets scaled with the current JS gain
     338             :     // @User: Standard
     339             :     // @Range: 0.5 4.0
     340             :     GSCALAR(throttle_gain, "JS_THR_GAIN", 1.0f),
     341             : 
     342             :     // @Param: FRAME_CONFIG
     343             :     // @DisplayName: Frame configuration
     344             :     // @Description: Set this parameter according to your vehicle/motor configuration
     345             :     // @User: Standard
     346             :     // @RebootRequired: True
     347             :     // @Values: 0:BlueROV1, 1:Vectored, 2:Vectored_6DOF, 3:Vectored_6DOF_90, 4:SimpleROV-3, 5:SimpleROV-4, 6:SimpleROV-5, 7:Custom
     348             :     GSCALAR(frame_configuration, "FRAME_CONFIG", AP_Motors6DOF::SUB_FRAME_VECTORED),
     349             : 
     350             :     // @Group: BTN0_
     351             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     352             :     GGROUP(jbtn_0,                   "BTN0_", JSButton),
     353             : 
     354             :     // @Group: BTN1_
     355             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     356             :     GGROUP(jbtn_1,                   "BTN1_", JSButton),
     357             : 
     358             :     // @Group: BTN2_
     359             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     360             :     GGROUP(jbtn_2,                   "BTN2_", JSButton),
     361             : 
     362             :     // @Group: BTN3_
     363             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     364             :     GGROUP(jbtn_3,                   "BTN3_", JSButton),
     365             : 
     366             :     // @Group: BTN4_
     367             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     368             :     GGROUP(jbtn_4,                   "BTN4_", JSButton),
     369             : 
     370             :     // @Group: BTN5_
     371             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     372             :     GGROUP(jbtn_5,                   "BTN5_", JSButton),
     373             : 
     374             :     // @Group: BTN6_
     375             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     376             :     GGROUP(jbtn_6,                   "BTN6_", JSButton),
     377             : 
     378             :     // @Group: BTN7_
     379             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     380             :     GGROUP(jbtn_7,                   "BTN7_", JSButton),
     381             : 
     382             :     // @Group: BTN8_
     383             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     384             :     GGROUP(jbtn_8,                   "BTN8_", JSButton),
     385             : 
     386             :     // @Group: BTN9_
     387             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     388             :     GGROUP(jbtn_9,                   "BTN9_", JSButton),
     389             : 
     390             :     // @Group: BTN10_
     391             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     392             :     GGROUP(jbtn_10,                   "BTN10_", JSButton),
     393             : 
     394             :     // @Group: BTN11_
     395             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     396             :     GGROUP(jbtn_11,                   "BTN11_", JSButton),
     397             : 
     398             :     // @Group: BTN12_
     399             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     400             :     GGROUP(jbtn_12,                   "BTN12_", JSButton),
     401             : 
     402             :     // @Group: BTN13_
     403             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     404             :     GGROUP(jbtn_13,                   "BTN13_", JSButton),
     405             : 
     406             :     // @Group: BTN14_
     407             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     408             :     GGROUP(jbtn_14,                   "BTN14_", JSButton),
     409             : 
     410             :     // @Group: BTN15_
     411             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     412             :     GGROUP(jbtn_15,                   "BTN15_", JSButton),
     413             : 
     414             :     // @Group: BTN16_
     415             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     416             :     GGROUP(jbtn_16,                   "BTN16_", JSButton),
     417             : 
     418             :     // @Group: BTN17_
     419             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     420             :     GGROUP(jbtn_17,                   "BTN17_", JSButton),
     421             : 
     422             :     // @Group: BTN18_
     423             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     424             :     GGROUP(jbtn_18,                   "BTN18_", JSButton),
     425             : 
     426             :     // @Group: BTN19_
     427             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     428             :     GGROUP(jbtn_19,                   "BTN19_", JSButton),
     429             : 
     430             :     // @Group: BTN20_
     431             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     432             :     GGROUP(jbtn_20,                   "BTN20_", JSButton),
     433             : 
     434             :     // @Group: BTN21_
     435             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     436             :     GGROUP(jbtn_21,                   "BTN21_", JSButton),
     437             : 
     438             :     // @Group: BTN22_
     439             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     440             :     GGROUP(jbtn_22,                   "BTN22_", JSButton),
     441             : 
     442             :     // @Group: BTN23_
     443             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     444             :     GGROUP(jbtn_23,                   "BTN23_", JSButton),
     445             : 
     446             :     // @Group: BTN24_
     447             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     448             :     GGROUP(jbtn_24,                   "BTN24_", JSButton),
     449             : 
     450             :     // @Group: BTN25_
     451             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     452             :     GGROUP(jbtn_25,                   "BTN25_", JSButton),
     453             : 
     454             :     // @Group: BTN26_
     455             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     456             :     GGROUP(jbtn_26,                   "BTN26_", JSButton),
     457             : 
     458             :     // @Group: BTN27_
     459             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     460             :     GGROUP(jbtn_27,                   "BTN27_", JSButton),
     461             : 
     462             :     // @Group: BTN28_
     463             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     464             :     GGROUP(jbtn_28,                   "BTN28_", JSButton),
     465             : 
     466             :     // @Group: BTN29_
     467             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     468             :     GGROUP(jbtn_29,                   "BTN29_", JSButton),
     469             : 
     470             :     // @Group: BTN30_
     471             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     472             :     GGROUP(jbtn_30,                   "BTN30_", JSButton),
     473             : 
     474             :     // @Group: BTN31_
     475             :     // @Path: ../libraries/AP_JSButton/AP_JSButton.cpp
     476             :     GGROUP(jbtn_31,                   "BTN31_", JSButton),
     477             : 
     478             :     // @Param: RC_SPEED
     479             :     // @DisplayName: ESC Update Speed
     480             :     // @Description: This is the speed in Hertz that your ESCs will receive updates
     481             :     // @Units: Hz
     482             :     // @Range: 50 490
     483             :     // @Increment: 1
     484             :     // @User: Advanced
     485             :     GSCALAR(rc_speed, "RC_SPEED",              RC_SPEED_DEFAULT),
     486             : 
     487             :     // @Param: ACRO_RP_P
     488             :     // @DisplayName: Acro Roll and Pitch P gain
     489             :     // @Description: Converts pilot roll and pitch into a desired rate of rotation in ACRO and SPORT mode.  Higher values mean faster rate of rotation.
     490             :     // @Range: 1 10
     491             :     // @User: Standard
     492             :     GSCALAR(acro_rp_p,                 "ACRO_RP_P",           ACRO_RP_P),
     493             : 
     494             :     // @Param: ACRO_YAW_P
     495             :     // @DisplayName: Acro Yaw P gain
     496             :     // @Description: Converts pilot yaw input into a desired rate of rotation.  Higher values mean faster rate of rotation.
     497             :     // @Range: 1 10
     498             :     // @User: Standard
     499             :     GSCALAR(acro_yaw_p,                 "ACRO_YAW_P",           ACRO_YAW_P),
     500             : 
     501             :     // @Param: ACRO_BAL_ROLL
     502             :     // @DisplayName: Acro Balance Roll
     503             :     // @Description: rate at which roll angle returns to level in acro mode.  A higher value causes the vehicle to return to level faster.
     504             :     // @Range: 0 3
     505             :     // @Increment: 0.1
     506             :     // @User: Advanced
     507             :     GSCALAR(acro_balance_roll,      "ACRO_BAL_ROLL",    ACRO_BALANCE_ROLL),
     508             : 
     509             :     // @Param: ACRO_BAL_PITCH
     510             :     // @DisplayName: Acro Balance Pitch
     511             :     // @Description: rate at which pitch angle returns to level in acro mode.  A higher value causes the vehicle to return to level faster.
     512             :     // @Range: 0 3
     513             :     // @Increment: 0.1
     514             :     // @User: Advanced
     515             :     GSCALAR(acro_balance_pitch,     "ACRO_BAL_PITCH",   ACRO_BALANCE_PITCH),
     516             : 
     517             :     // @Param: ACRO_TRAINER
     518             :     // @DisplayName: Acro Trainer
     519             :     // @Description: Type of trainer used in acro mode
     520             :     // @Values: 0:Disabled,1:Leveling,2:Leveling and Limited
     521             :     // @User: Advanced
     522             :     GSCALAR(acro_trainer,   "ACRO_TRAINER",     ACRO_TRAINER_LIMITED),
     523             : 
     524             :     // @Param: ACRO_EXPO
     525             :     // @DisplayName: Acro Expo
     526             :     // @Description: Acro roll/pitch Expo to allow faster rotation when stick at edges
     527             :     // @Values: 0:Disabled,0.1:Very Low,0.2:Low,0.3:Medium,0.4:High,0.5:Very High
     528             :     // @Range: -0.5 0.95
     529             :     // @User: Advanced
     530             :     GSCALAR(acro_expo,  "ACRO_EXPO",    ACRO_EXPO_DEFAULT),
     531             : 
     532             :     // variables not in the g class which contain EEPROM saved variables
     533             : 
     534             : #if AP_CAMERA_ENABLED
     535             :     // @Group: CAM
     536             :     // @Path: ../libraries/AP_Camera/AP_Camera.cpp
     537             :     GOBJECT(camera, "CAM", AP_Camera),
     538             : #endif
     539             : 
     540             : #if AP_RELAY_ENABLED
     541             :     // @Group: RELAY
     542             :     // @Path: ../libraries/AP_Relay/AP_Relay.cpp
     543             :     GOBJECT(relay,                  "RELAY", AP_Relay),
     544             : #endif
     545             : 
     546             :     // @Group: COMPASS_
     547             :     // @Path: ../libraries/AP_Compass/AP_Compass.cpp
     548             :     GOBJECT(compass,        "COMPASS_", Compass),
     549             : 
     550             :     // @Group: INS
     551             :     // @Path: ../libraries/AP_InertialSensor/AP_InertialSensor.cpp
     552             :     GOBJECT(ins,            "INS", AP_InertialSensor),
     553             : 
     554             :     // @Group: WP_
     555             :     // @Path: ../libraries/AC_WPNav/AC_WPNav.cpp
     556             :     GOBJECT(wp_nav, "WP_", AC_WPNav),
     557             : 
     558             :     // @Group: LOIT_
     559             :     // @Path: ../libraries/AC_WPNav/AC_Loiter.cpp
     560             :     GOBJECT(loiter_nav, "LOIT_", AC_Loiter),
     561             : 
     562             : #if CIRCLE_NAV_ENABLED
     563             :     // @Group: CIRCLE_
     564             :     // @Path: ../libraries/AC_WPNav/AC_Circle.cpp
     565             :     GOBJECT(circle_nav, "CIRCLE_",  AC_Circle),
     566             : #endif
     567             : 
     568             :     // @Group: ATC_
     569             :     // @Path: ../libraries/AC_AttitudeControl/AC_AttitudeControl.cpp,../libraries/AC_AttitudeControl/AC_AttitudeControl_Sub.cpp
     570             :     GOBJECT(attitude_control, "ATC_", AC_AttitudeControl_Sub),
     571             : 
     572             :     // @Group: PSC
     573             :     // @Path: ../libraries/AC_AttitudeControl/AC_PosControl.cpp
     574             :     GOBJECT(pos_control, "PSC", AC_PosControl),
     575             : 
     576             :     // @Group: AHRS_
     577             :     // @Path: ../libraries/AP_AHRS/AP_AHRS.cpp
     578             :     GOBJECT(ahrs,                   "AHRS_",    AP_AHRS),
     579             : 
     580             : #if HAL_MOUNT_ENABLED
     581             :     // @Group: MNT
     582             :     // @Path: ../libraries/AP_Mount/AP_Mount.cpp
     583             :     GOBJECT(camera_mount,           "MNT",  AP_Mount),
     584             : #endif
     585             : 
     586             :     // @Group: BATT
     587             :     // @Path: ../libraries/AP_BattMonitor/AP_BattMonitor.cpp
     588             :     GOBJECT(battery,                "BATT",         AP_BattMonitor),
     589             : 
     590             :     // @Group: ARMING_
     591             :     // @Path: AP_Arming_Sub.cpp,../libraries/AP_Arming/AP_Arming.cpp
     592             :     GOBJECT(arming, "ARMING_", AP_Arming_Sub),
     593             : 
     594             :     // @Group: BRD_
     595             :     // @Path: ../libraries/AP_BoardConfig/AP_BoardConfig.cpp
     596             :     GOBJECT(BoardConfig,            "BRD_",       AP_BoardConfig),
     597             : 
     598             : #if HAL_MAX_CAN_PROTOCOL_DRIVERS
     599             :     // @Group: CAN_
     600             :     // @Path: ../libraries/AP_CANManager/AP_CANManager.cpp
     601             :     GOBJECT(can_mgr,        "CAN_",       AP_CANManager),
     602             : #endif
     603             : 
     604             : #if AP_SIM_ENABLED
     605             :     // @Group: SIM_
     606             :     // @Path: ../libraries/SITL/SITL.cpp
     607             :     GOBJECT(sitl, "SIM_", SITL::SIM),
     608             : #endif
     609             : 
     610             :     // @Group: BARO
     611             :     // @Path: ../libraries/AP_Baro/AP_Baro.cpp
     612             :     GOBJECT(barometer, "BARO", AP_Baro),
     613             : 
     614             :     // GPS driver
     615             :     // @Group: GPS
     616             :     // @Path: ../libraries/AP_GPS/AP_GPS.cpp
     617             :     GOBJECT(gps, "GPS", AP_GPS),
     618             : 
     619             :     // Leak detector
     620             :     // @Group: LEAK
     621             :     // @Path: ../libraries/AP_LeakDetector/AP_LeakDetector.cpp
     622             :     GOBJECT(leak_detector, "LEAK", AP_LeakDetector),
     623             : 
     624             :     // @Group: SCHED_
     625             :     // @Path: ../libraries/AP_Scheduler/AP_Scheduler.cpp
     626             :     GOBJECT(scheduler, "SCHED_", AP_Scheduler),
     627             : 
     628             : #if AVOIDANCE_ENABLED
     629             :     // @Group: AVOID_
     630             :     // @Path: ../libraries/AC_Avoidance/AC_Avoid.cpp
     631             :     GOBJECT(avoid,      "AVOID_",   AC_Avoid),
     632             : #endif
     633             : 
     634             : #if HAL_RALLY_ENABLED
     635             :     // @Group: RALLY_
     636             :     // @Path: ../libraries/AP_Rally/AP_Rally.cpp
     637             :     GOBJECT(rally,      "RALLY_",   AP_Rally),
     638             : #endif
     639             : 
     640             :     // @Group: MOT_
     641             :     // @Path: ../libraries/AP_Motors/AP_Motors6DOF.cpp,../libraries/AP_Motors/AP_MotorsMulticopter.cpp
     642             :     GOBJECT(motors, "MOT_",         AP_Motors6DOF),
     643             : 
     644             : #if RCMAP_ENABLED
     645             :     // @Group: RCMAP_
     646             :     // @Path: ../libraries/AP_RCMapper/AP_RCMapper.cpp
     647             :     GOBJECT(rcmap, "RCMAP_",        RCMapper),
     648             : #endif
     649             : 
     650             : #if HAL_NAVEKF2_AVAILABLE
     651             :     // @Group: EK2_
     652             :     // @Path: ../libraries/AP_NavEKF2/AP_NavEKF2.cpp
     653             :     GOBJECTN(ahrs.ekf2.EKF2, NavEKF2, "EK2_", NavEKF2),
     654             : #endif
     655             : 
     656             : #if HAL_NAVEKF3_AVAILABLE
     657             :     // @Group: EK3_
     658             :     // @Path: ../libraries/AP_NavEKF3/AP_NavEKF3.cpp
     659             :     GOBJECTN(ahrs.ekf3.EKF3, NavEKF3, "EK3_", NavEKF3),
     660             : #endif
     661             : 
     662             :     // @Group: MIS_
     663             :     // @Path: ../libraries/AP_Mission/AP_Mission.cpp
     664             :     GOBJECT(mission, "MIS_",       AP_Mission),
     665             : 
     666             : #if AP_RANGEFINDER_ENABLED
     667             :     // @Group: RNGFND
     668             :     // @Path: ../libraries/AP_RangeFinder/AP_RangeFinder.cpp
     669             :     GOBJECT(rangefinder,   "RNGFND", RangeFinder),
     670             : 
     671             :     // @Param: RNGFND_SQ_MIN
     672             :     // @DisplayName: Rangefinder signal quality minimum
     673             :     // @Description: Minimum signal quality for good rangefinder readings
     674             :     // @Range: 0 100
     675             :     // @User: Advanced
     676             :     GSCALAR(rangefinder_signal_min, "RNGFND_SQ_MIN", RANGEFINDER_SIGNAL_MIN_DEFAULT),
     677             : 
     678             :     // @Param: SURFTRAK_DEPTH
     679             :     // @DisplayName: SURFTRAK minimum depth
     680             :     // @Description: Minimum depth to engage SURFTRAK mode
     681             :     // @Units: cm
     682             :     // @User: Standard
     683             :     GSCALAR(surftrak_depth, "SURFTRAK_DEPTH", SURFTRAK_DEPTH_DEFAULT),
     684             : #endif
     685             : 
     686             : #if AP_TERRAIN_AVAILABLE
     687             :     // @Group: TERRAIN_
     688             :     // @Path: ../libraries/AP_Terrain/AP_Terrain.cpp
     689             :     GOBJECT(terrain,                "TERRAIN_", AP_Terrain),
     690             : #endif
     691             : 
     692             : #if AP_OPTICALFLOW_ENABLED
     693             :     // @Group: FLOW
     694             :     // @Path: ../libraries/AP_OpticalFlow/AP_OpticalFlow.cpp
     695             :     GOBJECT(optflow,   "FLOW", AP_OpticalFlow),
     696             : #endif
     697             : 
     698             : #if OSD_ENABLED || OSD_PARAM_ENABLED
     699             :     // @Group: OSD
     700             :     // @Path: ../libraries/AP_OSD/AP_OSD.cpp
     701             :     GOBJECT(osd, "OSD", AP_OSD),
     702             : #endif
     703             : 
     704             : #if AP_RSSI_ENABLED
     705             :     // @Group: RSSI_
     706             :     // @Path: ../libraries/AP_RSSI/AP_RSSI.cpp
     707             :     GOBJECT(rssi, "RSSI_",  AP_RSSI),
     708             : #endif
     709             : 
     710             :     // @Group: NTF_
     711             :     // @Path: ../libraries/AP_Notify/AP_Notify.cpp
     712             :     GOBJECT(notify, "NTF_",  AP_Notify),
     713             : 
     714             :     // @Group:
     715             :     // @Path: Parameters.cpp
     716             :     GOBJECT(g2, "",  ParametersG2),
     717             : 
     718             :     // @Group:
     719             :     // @Path: ../libraries/AP_Vehicle/AP_Vehicle.cpp
     720             :     PARAM_VEHICLE_INFO,
     721             : 
     722             : #if HAL_GCS_ENABLED
     723             :     // @Group: MAV
     724             :     // @Path: ../libraries/GCS_MAVLink/GCS.cpp
     725             :     GOBJECT(_gcs,           "MAV",  GCS),
     726             : #endif
     727             : 
     728             :     AP_VAREND
     729             : };
     730             : 
     731             : /*
     732             :   2nd group of parameters
     733             :  */
     734             : const AP_Param::GroupInfo ParametersG2::var_info[] = {
     735             : 
     736             :     // 1 was AP_Stats
     737             : 
     738             : #if HAL_PROXIMITY_ENABLED
     739             :     // @Group: PRX
     740             :     // @Path: ../libraries/AP_Proximity/AP_Proximity.cpp
     741             :     AP_SUBGROUPINFO(proximity, "PRX", 2, ParametersG2, AP_Proximity),
     742             : #endif
     743             : 
     744             :     // 3 was AP_Gripper
     745             : 
     746             :     // @Group: SERVO
     747             :     // @Path: ../libraries/SRV_Channel/SRV_Channels.cpp
     748             :     AP_SUBGROUPINFO(servo_channels, "SERVO", 16, ParametersG2, SRV_Channels),
     749             : 
     750             :     // @Group: RC
     751             :     // @Path: ../libraries/RC_Channel/RC_Channels_VarInfo.h
     752             :     AP_SUBGROUPINFO(rc_channels, "RC", 17, ParametersG2, RC_Channels),
     753             : 
     754             :     // 18 was scripting
     755             :     // 19 was ORIGIN_LAT
     756             :     // 20 was ORIGIN_LON
     757             :     // 21 was ORIGIN_ALT
     758             : 
     759             :     // @Param: SFC_NOBARO_THST
     760             :     // @DisplayName: Surface mode throttle output when no barometer is available
     761             :     // @Description: Surface mode throttle output when no borometer is available. 100% is full throttle. -100% is maximum throttle downwards
     762             :     // @Units: %
     763             :     // @User: Standard
     764             :     // @Range: -100 100
     765             :     AP_GROUPINFO("SFC_NOBARO_THST", 22, ParametersG2, surface_nobaro_thrust, 10),
     766             : 
     767             :     // @Group: ACTUATOR
     768             :     // @Path: ../ArduSub/actuators.cpp
     769             :     AP_SUBGROUPINFO(actuators, "ACTUATOR", 23, ParametersG2, Actuators),
     770             : 
     771             :     // Hidden param used as a flag for param conversion
     772             :     // This allows one time conversion while allowing user to flash between versions with and without converted params
     773             :     AP_GROUPINFO_FLAGS("PARM_FMT_VER", 24, ParametersG2, param_conversion_increment, 0, AP_PARAM_FLAG_HIDDEN),
     774             : 
     775             :     AP_GROUPEND
     776             : };
     777             : 
     778             : /*
     779             :   constructor for g2 object
     780             :  */
     781          83 : ParametersG2::ParametersG2()
     782             : {
     783          83 :     AP_Param::setup_object_defaults(this, var_info);
     784          83 : }
     785             : 
     786          83 : void Sub::load_parameters()
     787             : {
     788          83 :     AP_Vehicle::load_parameters(g.format_version, Parameters::k_format_version);
     789             : 
     790          83 :     AP_Param::set_frame_type_flags(AP_PARAM_FRAME_SUB);
     791             : 
     792          83 :     AP_Param::set_defaults_from_table(defaults_table, ARRAY_SIZE(defaults_table));
     793             :     // We should ignore this parameter since ROVs are neutral buoyancy
     794          83 :     AP_Param::set_by_name("MOT_THST_HOVER", 0.5);
     795             : 
     796             :     // PARAMETER_CONVERSION - Added: Jul-2025 for ArduPilot-4.7
     797             : #if AP_RPM_ENABLED
     798          83 :     AP_Param::convert_class(g.k_param_rpm_sensor_old, &rpm_sensor, rpm_sensor.var_info, 0, true, true);
     799             : #endif
     800             : 
     801             :     static const AP_Param::G2ObjectConversion g2_conversions[] {
     802             : #if AP_STATS_ENABLED
     803             :     // PARAMETER_CONVERSION - Added: Jan-2024
     804          83 :         { &stats, stats.var_info, 1 },
     805             : #endif
     806             : #if AP_SCRIPTING_ENABLED
     807             :     // PARAMETER_CONVERSION - Added: Jan-2024
     808          83 :         { &scripting, scripting.var_info, 18 },
     809             : #endif
     810             : #if AP_GRIPPER_ENABLED
     811             :     // PARAMETER_CONVERSION - Added: Feb-2024
     812          83 :         { &gripper, gripper.var_info, 3 },
     813             : #endif
     814          83 :     };
     815             : 
     816          83 :     AP_Param::convert_g2_objects(&g2, g2_conversions, ARRAY_SIZE(g2_conversions));
     817             : 
     818             :     // PARAMETER_CONVERSION - Added: Feb-2024
     819             : #if HAL_LOGGING_ENABLED
     820          83 :     AP_Param::convert_class(g.k_param_logger, &logger, logger.var_info, 0, true);
     821             : #endif
     822             : 
     823             :     static const AP_Param::TopLevelObjectConversion toplevel_conversions[] {
     824             : #if AP_SERIALMANAGER_ENABLED
     825             :         // PARAMETER_CONVERSION - Added: Feb-2024
     826          83 :         { &serial_manager, serial_manager.var_info, Parameters::k_param_serial_manager_old },
     827             : #endif
     828          83 :     };
     829             : 
     830          83 :     AP_Param::convert_toplevel_objects(toplevel_conversions, ARRAY_SIZE(toplevel_conversions));
     831             : 
     832             : #if HAL_GCS_ENABLED
     833             :     // Move parameters into new MAV_ parameter namespace
     834             :     // PARAMETER_CONVERSION - Added: Mar-2025
     835             :     {
     836             :         static const AP_Param::ConversionInfo gcs_conversion_info[] {
     837             :             { Parameters::k_param_sysid_this_mav_old, 0, AP_PARAM_INT16,  "MAV_SYSID" },
     838             :             { Parameters::k_param_sysid_my_gcs_old, 0, AP_PARAM_INT16, "MAV_GCS_SYSID" },
     839             :         };
     840          83 :         AP_Param::convert_old_parameters(&gcs_conversion_info[0], ARRAY_SIZE(gcs_conversion_info));
     841             :     }
     842             : #endif  // HAL_GCS_ENABLED
     843             : 
     844             :     // upgrade attitude controller parameters
     845          83 :     sub.attitude_control.convert_parameters();
     846             : 
     847             :     // upgrade waypoint navigation parameters
     848          83 :     wp_nav.convert_parameters();
     849             : 
     850             :     // upgrade loiter navigation parameters
     851          83 :     loiter_nav.convert_parameters();
     852             : 
     853             : #if CIRCLE_NAV_ENABLED
     854          83 :     circle_nav.convert_parameters();
     855             : #endif
     856             : 
     857             :     // PARAMETER_CONVERSION - Added: Jan-2026
     858             :     // move ORIGIN_LAT, ORIGIN_LON, ORIGIN_ALT to AHRS
     859             :     static const AP_Param::ConversionInfo origin_conversion_info[] {
     860             :         { 2, 19, AP_PARAM_FLOAT, "AHRS_ORIGIN_LAT" },   // ORIGIN_LAT moved to AHRS_ORIGIN_LAT
     861             :         { 2, 20, AP_PARAM_FLOAT, "AHRS_ORIGIN_LON" },   // ORIGIN_LON moved to AHRS_ORIGIN_LON
     862             :         { 2, 21, AP_PARAM_FLOAT, "AHRS_ORIGIN_ALT" },   // ORIGIN_ALT moved to AHRS_ORIGIN_ALT
     863             :     };
     864          83 :     AP_Param::convert_old_parameters(&origin_conversion_info[0], ARRAY_SIZE(origin_conversion_info));
     865          83 : }
     866             : 
     867             : #if LEAKDETECTOR_MAX_INSTANCES > 0
     868             : // PARAMETER_CONVERSION - Added: Dec-2025
     869             : // Deals with leak detector getting misconfigured when updating from Sub 4.1
     870          82 : void Sub::update_leak_pins()
     871             : {
     872         328 :     for (uint8_t instance = 0; instance < LEAKDETECTOR_MAX_INSTANCES; instance++) {
     873         246 :         if (leak_detector.get_pin(instance) <= 0) {
     874             :             // leak detector does not use pin
     875         246 :             continue;
     876             :         }
     877             :         uint8_t servo_channel;
     878           0 :         if (!hal.gpio->pin_to_servo_channel(leak_detector.get_pin(instance), servo_channel)) {
     879             :             // leak detector pin does not map to a servo channel
     880           0 :             continue;
     881             :         }
     882           0 :         if (SRV_Channels::is_GPIO(servo_channel)) {
     883             :             // servo channel is already set to GPIO
     884           0 :             continue;
     885             :         }
     886           0 :         if (SRV_Channels::channel_function(servo_channel) != SRV_Channel::Function::k_none) {
     887             :             // servo channel is already set to a function
     888           0 :             gcs().send_text(MAV_SEVERITY_WARNING, "Leak detector %u error. Please set SERVO%u_FUNCTION to GPIO", instance + 1, servo_channel + 1);
     889           0 :             continue;
     890             :         }
     891             :         // servo channel is disabled, let's set it to GPIO for the user
     892           0 :         gcs().send_text(MAV_SEVERITY_INFO, "Leak detector %u pin (servo %u) auto-set to GPIO", instance + 1, servo_channel + 1);
     893             :         char param_name[20];
     894           0 :         snprintf(param_name, sizeof(param_name), "SERVO%u_FUNCTION", servo_channel + 1);
     895           0 :         AP_Param::set_and_save_by_name(param_name, static_cast<int>(SRV_Channel::Function::k_GPIO));
     896             :     }
     897          82 : }
     898             : #endif
     899             : 
     900             : #if AP_RELAY_ENABLED
     901             : // PARAMETER_CONVERSION - Added: Dec-2025
     902             : // Deals with relay getting misconfigured when updating from Sub 4.1
     903          82 : void Sub::update_relay_pins()
     904             : {
     905         574 :     for (uint8_t instance = 0; instance < AP_RELAY_NUM_RELAYS; instance++) {
     906             :         uint8_t servo_channel;
     907             :         uint8_t pin;
     908         492 :         if (!relay.get_pin_by_instance(instance, pin) || !hal.gpio->pin_to_servo_channel(pin, servo_channel)) {
     909             :             // instance does not use pin or pin does not map to a servo channel
     910         492 :             continue;
     911             :         }
     912           0 :         if (!relay.enabled(instance) || SRV_Channels::is_GPIO(servo_channel)) {
     913             :             // instance is not enabled or servo channel is already set to GPIO
     914           0 :             continue;
     915             :         }
     916           0 :         if (SRV_Channels::channel_function(servo_channel) != SRV_Channel::Function::k_none) {
     917             :             // servo channel is already set to a function
     918           0 :             gcs().send_text(MAV_SEVERITY_WARNING, "Relay %u error. Please set SERVO%u_FUNCTION to GPIO", instance + 1, servo_channel + 1);
     919           0 :             continue;
     920             :         }
     921             :         // servo channel is disabled, let's set it to GPIO for the user
     922           0 :         gcs().send_text(MAV_SEVERITY_INFO, "Relay %u pin (servo %u) auto-set to GPIO", instance + 1, servo_channel + 1);
     923             :         char param_name[20];
     924           0 :         snprintf(param_name, sizeof(param_name), "SERVO%u_FUNCTION", servo_channel + 1);
     925           0 :         AP_Param::set_and_save_by_name(param_name, static_cast<int>(SRV_Channel::Function::k_GPIO));
     926             :     }
     927          82 : }
     928             : #endif
     929             : 
     930             : // Helper function to set servo function by channel number, 1-indexed
     931           0 : static void set_servo_function(uint8_t channel, SRV_Channel::Function function)
     932             : {
     933             :     char param_name[20];
     934           0 :     snprintf(param_name, sizeof(param_name), "SERVO%u_FUNCTION", channel);
     935           0 :     AP_Param::set_and_save_by_name(param_name, static_cast<int>(function));
     936           0 : }
     937             : 
     938             : 
     939             : // PARAMETER_CONVERSION - Added: Mar-2026
     940           9 : void Sub::update_actuators_from_jsbuttons()
     941             : {
     942             :     /*
     943             :     This function is used to update parameters from Sub <=4.5.4 to the newer actuators implementation.
     944             :     servo_1_inc/min/dec/etc.. were hard-coded to work only on channels 9,10,11. This update means we now have to change
     945             :     these functions to the corresponding actuator function to keep the same functionality.
     946             :     For each of SERVO9,10,11, if they are set to DISABLED, check if there are joystick buttons set to actuator functions.
     947             :     if so, and no other channel is set to that actuator function, set the servo to the actuator function.
     948             :     */
     949             : 
     950             :     // Configuration constants
     951           9 :     const uint8_t FIRST_LEGACY_CHANNEL = 9;
     952           9 :     const uint8_t NUM_LEGACY_ACTUATORS = 3;
     953           9 :     const size_t FUNCTIONS_PER_SERVO = 9;
     954             : 
     955             :     // Legacy servo button functions mapped to actuators 1-3
     956             :     static constexpr JSButton::button_function_t servo_functions[NUM_LEGACY_ACTUATORS][FUNCTIONS_PER_SERVO] = {
     957             :         {
     958             :             // Actuator 1 (was servo_1_*)
     959             :             JSButton::button_function_t::k_servo_1_inc,
     960             :             JSButton::button_function_t::k_servo_1_dec,
     961             :             JSButton::button_function_t::k_servo_1_min,
     962             :             JSButton::button_function_t::k_servo_1_max,
     963             :             JSButton::button_function_t::k_servo_1_center,
     964             :             JSButton::button_function_t::k_servo_1_min_momentary,
     965             :             JSButton::button_function_t::k_servo_1_max_momentary,
     966             :             JSButton::button_function_t::k_servo_1_min_toggle,
     967             :             JSButton::button_function_t::k_servo_1_max_toggle
     968             :         },
     969             :         {
     970             :             // Actuator 2 (was servo_2_*)
     971             :             JSButton::button_function_t::k_servo_2_inc,
     972             :             JSButton::button_function_t::k_servo_2_dec,
     973             :             JSButton::button_function_t::k_servo_2_min,
     974             :             JSButton::button_function_t::k_servo_2_max,
     975             :             JSButton::button_function_t::k_servo_2_center,
     976             :             JSButton::button_function_t::k_servo_2_min_momentary,
     977             :             JSButton::button_function_t::k_servo_2_max_momentary,
     978             :             JSButton::button_function_t::k_servo_2_min_toggle,
     979             :             JSButton::button_function_t::k_servo_2_max_toggle
     980             :         },
     981             :         {
     982             :             // Actuator 3 (was servo_3_*)
     983             :             JSButton::button_function_t::k_servo_3_inc,
     984             :             JSButton::button_function_t::k_servo_3_dec,
     985             :             JSButton::button_function_t::k_servo_3_min,
     986             :             JSButton::button_function_t::k_servo_3_max,
     987             :             JSButton::button_function_t::k_servo_3_center,
     988             :             JSButton::button_function_t::k_servo_3_min_momentary,
     989             :             JSButton::button_function_t::k_servo_3_max_momentary,
     990             :             JSButton::button_function_t::k_servo_3_min_toggle,
     991             :             JSButton::button_function_t::k_servo_3_max_toggle
     992             :         }
     993             :     };
     994             : 
     995             :     // Target actuator functions for assignment
     996             :     static constexpr SRV_Channel::Function actuator_functions[NUM_LEGACY_ACTUATORS] = {
     997             :         SRV_Channel::Function::k_actuator1,
     998             :         SRV_Channel::Function::k_actuator2,
     999             :         SRV_Channel::Function::k_actuator3
    1000             :     };
    1001             : 
    1002             :     // Process legacy channels 9-11
    1003          36 :     for (uint8_t actuator_idx = 0; actuator_idx < NUM_LEGACY_ACTUATORS; actuator_idx++) {
    1004          27 :         const uint8_t channel = FIRST_LEGACY_CHANNEL + actuator_idx;
    1005          27 :         const auto target_function = actuator_functions[actuator_idx];
    1006             : 
    1007             :         // Skip if actuator function already assigned to any channel
    1008             :         uint8_t existing_channel;
    1009          27 :         if (SRV_Channels::find_channel(target_function, existing_channel)) {
    1010          18 :             continue;
    1011             :         }
    1012             : 
    1013             :         // Skip if channel is not disabled
    1014          27 :         if (SRV_Channels::channel_function(channel - 1) != SRV_Channel::Function::k_none) {
    1015          18 :             continue;
    1016             :         }
    1017             : 
    1018             :         // Check if any servo/actuator buttons are assigned
    1019           9 :         bool has_assigned_button = false;
    1020          90 :         for (size_t func_idx = 0; func_idx < FUNCTIONS_PER_SERVO; func_idx++) {
    1021          81 :             if (sub.jsbutton_function_is_assigned(servo_functions[actuator_idx][func_idx])) {
    1022           0 :                 has_assigned_button = true;
    1023           0 :                 break;
    1024             :             }
    1025             :         }
    1026             : 
    1027           9 :         if (has_assigned_button) {
    1028             :             // Assign actuator function to preserve legacy behavior
    1029           0 :             set_servo_function(channel, target_function);
    1030             :         }
    1031             :     }
    1032           9 : }
    1033             : 
    1034             : // PARAMETER_CONVERSION - Added: Mar-2026
    1035           9 : void Sub::update_lights_from_rcin()
    1036             : {
    1037             :     /*
    1038             :     Maps older systems from using RCIN9 and RCIN10 to using lights1 and lights2.
    1039             :     This is only done if there are joystick buttons assigned to the lights functions and there are no channels assigned to the lights functions.
    1040             :     */
    1041             : 
    1042           9 :     const uint8_t NUM_LIGHTS = 2;
    1043           9 :     const uint8_t FUNCTIONS_PER_LIGHT = 3;
    1044             :     static constexpr JSButton::button_function_t lights_button_functions[NUM_LIGHTS][FUNCTIONS_PER_LIGHT] = {
    1045             :         {
    1046             :             JSButton::button_function_t::k_lights1_brighter,
    1047             :             JSButton::button_function_t::k_lights1_dimmer,
    1048             :             JSButton::button_function_t::k_lights1_cycle,
    1049             :         },
    1050             :         {
    1051             :             JSButton::button_function_t::k_lights2_brighter,
    1052             :             JSButton::button_function_t::k_lights2_dimmer,
    1053             :             JSButton::button_function_t::k_lights2_cycle,
    1054             :         }
    1055             :     };
    1056             : 
    1057             :     // New, dedicated lights output functions
    1058           9 :     const SRV_Channel::Function lights_functions[NUM_LIGHTS] = {
    1059             :         SRV_Channel::Function::k_lights1,
    1060             :         SRV_Channel::Function::k_lights2
    1061             :     };
    1062             : 
    1063             :     // Legacy, overloaded and hardcoded RCIN passthrough outputs
    1064           9 :     const SRV_Channel::Function rcin_functions[NUM_LIGHTS] = {
    1065             :         SRV_Channel::Function::k_rcin9,
    1066             :         SRV_Channel::Function::k_rcin10
    1067             :     };
    1068             : 
    1069             :     // Confirm the new output is not already assigned, and extract the legacy output for remapping
    1070          27 :     for (uint8_t light = 0; light < NUM_LIGHTS; light++) {
    1071             :         uint8_t existing_channel;
    1072          18 :         if (SRV_Channels::find_channel(lights_functions[light], existing_channel)
    1073          18 :             || !SRV_Channels::find_channel(rcin_functions[light], existing_channel)) {
    1074          18 :             continue;
    1075             :         }
    1076             :         // We have a potential lights RCIN channel. Do we have lights buttons?
    1077           0 :         for (uint8_t func_idx = 0; func_idx < FUNCTIONS_PER_LIGHT; func_idx++) {
    1078           0 :             if (sub.jsbutton_function_is_assigned(lights_button_functions[light][func_idx])) {
    1079             :                 // We have buttons assigned to lights. Set the channel to the new, dedicated lights function.
    1080           0 :                 set_servo_function(existing_channel + 1, lights_functions[light]);
    1081           0 :                 break;
    1082             :             }
    1083             :         }
    1084             :     }
    1085           9 : }

Generated by: LCOV version 1.14