local SCRIPT_NAME = 'MultiSelect' local FILE_DIRECTORY = 'scripts' local FILE_PREFIX = 'mission_' local FILE_EXTENSION = 'waypoints' local LONG_PRESS_MS = 500 local RUN_INTERVAL_MS = 30 local SBY_INTERVAL_MS = 1000 local MAV_SEVERITY_INFO = 6 local PARAM_PREFIX = 'MLT' local PARAM_TABLE_KEY = 100 -- unique index value between 0 and 200 local PARAM_TABLE = { -- { name, default value }, { 'FUNCTION', 300 }, -- option assigned to RC switch (e.g., 300, 301, etc) { 'POSITIONS', 3 }, -- 0 to disable, 1 for momentary, otherwise number of switch positions } local function add_params(key, prefix, tbl) assert(param:add_table(key, prefix, #tbl), string.format('Could not add %s param table.', prefix)) for num, data in ipairs(tbl) do assert(param:add_param(key, num, data[1], data[2]), string.format('Could not add %s%s.', prefix, data[1])) end end add_params(PARAM_TABLE_KEY, PARAM_PREFIX .. '_', PARAM_TABLE) local function msg(text) return string.format('%s: %s', SCRIPT_NAME, text) end local sw_function = assert(param:get('MLT_FUNCTION'), 'MLT_FUNCTION parameter not found') local switch = assert(rc:find_channel_for_option(sw_function), string.format('RC option %d not assigned', sw_function)) local num_sw_positions = -1 local last_sw_position = nil local last_sw_change = uint32_t(0) local file_index = 0 local function load_mission_file(index) -- ! placeholder for example's sake local filename = string.format('%s/%s%d.%s', FILE_DIRECTORY, FILE_PREFIX, index, FILE_EXTENSION) gcs:send_text(MAV_SEVERITY_INFO, msg(string.format('Loading %s', filename))) end local function poll_switch() local sw_position = -1 if num_sw_positions <= 3 then sw_position = switch:get_aux_switch_pos() if sw_position == 2 and num_sw_positions == 2 then sw_position = 1 end else sw_position = (switch:norm_input_ignore_trim() + 1) * (num_sw_positions - 1) / 2 sw_position = tonumber(string.format('%.0f', sw_position)) or -1 -- stupid Lua rounding trick end if not last_sw_position then -- avoid triggering switch change logic if last_sw_position is not yet set last_sw_position = sw_position return nil end if sw_position ~= last_sw_position then last_sw_position = sw_position return sw_position end return nil end function do_multi_select() local switch_position = poll_switch() if switch_position then load_mission_file(switch_position) end return do_multi_select, RUN_INTERVAL_MS end local num_files = 9 -- ! placeholder - you could achieve this dynamically by checking if files exist function do_momentary_select() local previous_switch_position = last_sw_position local switch_position = poll_switch() if not switch_position then return do_momentary_select, RUN_INTERVAL_MS end if previous_switch_position == 0 then last_sw_change = millis() return do_momentary_select, RUN_INTERVAL_MS end local long_press = (millis() - last_sw_change) > LONG_PRESS_MS if long_press then load_mission_file(file_index) return do_momentary_select, RUN_INTERVAL_MS end file_index = (file_index + 1) % num_files gcs:send_text(MAV_SEVERITY_INFO, msg(string.format('Selected %s%d', FILE_PREFIX, file_index))) return do_momentary_select, RUN_INTERVAL_MS end function standby() num_sw_positions = assert(param:get('MLT_POSITIONS'), 'MLT_POSITIONS parameter not found') if num_sw_positions > 1 then return do_multi_select, RUN_INTERVAL_MS end if num_sw_positions == 1 then return do_momentary_select, RUN_INTERVAL_MS end return standby, SBY_INTERVAL_MS end gcs:send_text(MAV_SEVERITY_INFO, msg('Script Active')) return standby, SBY_INTERVAL_MS