--[[ add ALT_OFFSET parameter for copter This behaves similarly to ALT_OFFSET in plane. It operators only in AUTO mode, and slews the BARO_ALT_OFFSET to allow for change of altitude without mission change --]] local PARAM_TABLE_KEY = 79 local PARAM_TABLE_PREFIX = "ALT_" local MODE_AUTO = 3 local LOOP_RATE = 50 -- bind a parameter to a variable function bind_param(name) local p = Parameter() assert(p:init(name), string.format('could not find %s parameter', name)) return p end -- add a parameter and bind it to a variable function bind_add_param(name, idx, default_value) assert(param:add_param(PARAM_TABLE_KEY, idx, name, default_value), string.format('could not add param %s', name)) return bind_param(PARAM_TABLE_PREFIX .. name) end -- setup SHIP specific parameters assert(param:add_table(PARAM_TABLE_KEY, PARAM_TABLE_PREFIX, 2), 'could not add param table') ALT_OFFSET = bind_add_param('OFFSET', 1, 0) ALT_OFFSET_RT = bind_add_param('OFFSET_RT', 2, 1) BARO_ALT_OFFSET = bind_param("BARO_ALT_OFFSET") local vehicle_mode = nil -- constrain a value between limits function constrain(v, vmin, vmax) if v < vmin then v = vmin end if v > vmax then v = vmax end return v end -- main update function function update() vehicle_mode = vehicle:get_mode() if vehicle_mode ~= MODE_AUTO then BARO_ALT_OFFSET:set(0) return end if not arming:is_armed() then -- zero offset when disarmed BARO_ALT_OFFSET:set(0) ALT_OFFSET:set(0) end local target = ALT_OFFSET:get() * -1.0 local current = BARO_ALT_OFFSET:get() local delta = target - current local dt = 1.0 / LOOP_RATE local delta_max = ALT_OFFSET_RT:get() * dt delta = constrain(delta, -delta_max, delta_max) BARO_ALT_OFFSET:set(current + delta) end -- wrapper around update(). This calls update() at 20Hz, -- and if update faults then an error is displayed, but the script is not -- stopped function protected_wrapper() local success, err = pcall(update) if not success then gcs:send_text(0, "Internal Error: " .. err) -- when we fault we run the update function again after 1s, slowing it -- down a bit so we don't flood the console with errors return protected_wrapper, 1000 end return protected_wrapper, 1000/LOOP_RATE end gcs:send_text(0, "ALT_OFFSET handler loaded") -- start running update loop return protected_wrapper()