Mavproxy中运行Lua脚本遭遇EOF错误求助
解决Mavproxy Lua脚本启动报错及逻辑问题
一、修复触发当前报错的语法问题
你看到的AP: PreArm: Scripting: Error: ./scripts/teste.lua:53: ex是截断的语法错误提示,根源是代码里用了HTML转义字符:
- 所有
"要替换为Lua原生双引号" - 所有
<要替换为Lua原生小于号<
Lua无法识别HTML实体,这会直接导致脚本解析失败,替换后即可解决启动报错。
二、修复计数器逻辑失效问题
main函数内的local counter = 0每次调用都会重置为0,导致counter %5 ==0永远无法成立,update()函数永远不会执行。需要把计数器移到函数外部,保持状态:
local counter = 0 -- 放到main函数外,避免每次重置 function main() counter = counter + 1 if counter % 5 == 0 then update() end -- ... 其余代码不变 end
三、修复距离计算逻辑错误
直接用经纬度差值计算距离是错误的(经纬度是角度单位,不是平面坐标),需要用Haversine公式转换为实际米数,替换land函数中的距离计算部分:
-- 替换原距离计算代码 local lat1 = location.lat() * math.pi / 180 local lon1 = location.lng() * math.pi / 180 local lat2 = pos.x * math.pi / 180 local lon2 = pos.y * math.pi / 180 local dlat = lat2 - lat1 local dlon = lon2 - lon1 local a = math.sin(dlat/2)^2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)^2 local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a)) local distance = 6371000 * c -- 地球半径约6371000米,结果为实际距离(米)
四、优化模式设置的可读性与可靠性
避免用数字直接指代飞行模式,改用模式名称(如"AUTO"、"LAND"),减少出错概率:
-- 替换update函数中的模式判断 local mode = vehicle:get_mode() if mode ~= "AUTO" then gcs:send_text(6, "Switching to AUTO.MISSION...") vehicle:set_mode("AUTO") end -- 替换land函数中的模式设置 vehicle:set_mode("LAND")
完整修正后的代码
local counter = 0 function update() -- 读取并验证航点 local item = mission:get_item(0) if not item then gcs:send_text(6, "No waypoint loaded.") return update, 3000 end -- 向GCS发送航点信息 gcs:send_text(6, string.format("Waypoint 0: lat=%.6f, lon=%.6f, alt=%.2f", item.x, item.y, item.z)) -- 检查并切换到AUTO模式 local mode = vehicle:get_mode() if mode ~= "AUTO" then gcs:send_text(6, "Switching to AUTO.MISSION...") vehicle:set_mode("AUTO") else gcs:send_text(6, "Already in AUTO.MISSION.") end return update, 5000 end function land() local pos = mission:get_item(0) if not pos then gcs:send_text(6, "No waypoint loaded.") return land, 1000 end local location = ahrs:get_position() if not location then gcs:send_text(6, "Cannot get current vehicle position.") return land, 1000 end -- 使用Haversine公式计算实际距离(米) local lat1 = location.lat() * math.pi / 180 local lon1 = location.lng() * math.pi / 180 local lat2 = pos.x * math.pi / 180 local lon2 = pos.y * math.pi / 180 local dlat = lat2 - lat1 local dlon = lon2 - lon1 local a = math.sin(dlat/2)^2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)^2 local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a)) local distance = 6371000 * c -- 距离小于5米时切换到LAND模式 if distance < 5 then gcs:send_text(6, "Distance is less than 5 meters. Landing...") vehicle:set_mode("LAND") else gcs:send_text(6, "Distance is greater than 5 meters. Not landing.") end gcs:send_text(6, string.format("Distance between pos and item: %.2f meters", distance)) return land, 2000 end function main() counter = counter + 1 -- 每5秒执行一次update if counter % 5 == 0 then update() end -- 每秒执行一次land land() return main, 1000 end return main()
内容的提问来源于stack exchange,提问作者Eduardo Brioso
相关产品推荐
相关产品推荐

