Derive position of mower deck - by counting how long the servos are running

Greetings from very hot and sunny new zealand. Too hot - so im hiding inside on my laptop.

Our mower deck goes up and down - there are limit switches - top and below ground level somewhere.
The servos are on or off driving a linear servo - ie not proportional just off or up or down. Its approx 5mm of servo travel per second - with 50mm “throw”

Question - is Ardupilot/Lua up to counting how many “ticks” a servo is running both up/down - and derive the position of the deck ? Im guessing the code would need to run with high frequency, and update a parameter deck_height.

ie from Top/Limit - 5seconds at 5mm/sec - must mean 25mm or mid position
if rc.ch2 => high then deck_height goes up +1 “ticks”
if rc.ch2 <= low then deck_height goes up -1 “ticks”

recalibrating the absolute position with the top limit switch should be doable.
This is quicker than figuring out a deck height measurement - Thoughts ?

Log of mower hitting long grass, and me manually lifting deck to bring revs up…

You could do it with timings from the top position and have your levels as 1 sec… 2 sec 3 sec etc. Or you could do with stepper motor or there are large linear servos that accept 1000…2000us rc signal. But multi level is hardly something that would need to be automated and set for different levels, you could do max height and one cutting height just with gpio

thanks - counting timings from the top is the plan - or at least until we get a linear measure thing working.It doesnt need to be 100% accurate - as the deck level is moved not too often.

Oh, i see you are trying lifting the deck to prevent motor stalls when you get to longer grass.
This seems really like the wrong idea, you will just get longer patches all over the place, what you need to do is reduce the travel speed to maintain engine rpm with loop control, then as you get past the thicker/longer grass it will speed back up to the set waypoint speed

yep - agreed. This is like strategy#2, i’ve taken Yuri’s rough terrain lua script and have it watching RPM - if it goes down, slows to half WP_SPEED (or stops if revs get too low) until revs get back up then resumes.

Thats working (at least the script is running - my tuning needs a few more runs to get right)

This deck height from servo thing is plan-B. Also we figure once the mower is fully operational, the lawns will be way more consistent - as mowed more frequently…

cheers

Follow up post - Its working. Im getting good consistent relative deck height values.

My (beginners) code below. The logic is good - testing it up and down over a few cycles, its back to the same position within a few millimeters. All bets are off when it hits a limit switch - the counters stlll go up/down while the servo is stopped.

My deck up/down servo is on/off which gives me consistency over time.
Its not a substitute for actual deck height readings, but in lieu of hardware…

The height is returned into mission planner via gcs:send_named_float() as MAV_DECK and can be pinned into the quick tab.

--------    USER EDITABLE GLOBALS  --------
local SWITCH_CHANNEL = 2    -- RC input 2 or Servo Chan 5
local Deck_Up       = 1600  -- or above = +1 
local Deck_Down     = 1400  -- or below = -1
local DeckHeight    = 0      -- initial position
local LastDeckHeight = 0
local FREQUENCY      = 100   -- (ms) how often to run this script (100 to 250 works well)
-------- END USER EDITABLE GLOBALS --------

local lastPwm = rc:get_pwm(SWITCH_CHANNEL)
gcs:send_text(0, "DeckHeight: Script active")

function update()
	local pwm = rc:get_pwm(SWITCH_CHANNEL)
	if (pwm < Deck_Up and pwm > Deck_Down) then return update, FREQUENCY end
	lastPwm = pwm
	
	if pwm < Deck_Down  then
		DeckHeight = DeckHeight -1
		gcs:send_named_float('Deck',DeckHeight)
		return update, FREQUENCY
		
	elseif pwm > Deck_Up then
		DeckHeight = DeckHeight +1
		gcs:send_named_float('Deck',DeckHeight)
		return update, FREQUENCY
		
	end
	
	gcs:send_text(0, string.format("Deck: %0.1f ",DeckHeight))
	
	if DeckHeight ~= LastDeckHeight then
		gcs:send_text(0, string.format("Deck: %0.1f ",DeckHeight))
		LastDeckHeight = DeckHeight
	end
	return update, 4000
	
end
return update()

Nice work, i haven’t got to the stage of any of my own scripting yet, so far i have just tried other peoples work