Skip to content

Commit 0a3723e

Browse files
committed
Update SoarNav.lua
1 parent 38ca3f5 commit 0a3723e

File tree

1 file changed

+25
-25
lines changed

1 file changed

+25
-25
lines changed

libraries/AP_Scripting/applets/SoarNav.lua

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
--[[
22
SoarNav: an advanced feature for hunting thermals by Marco Robustini.
3-
-- Version 0.9.1 - 2025/07/29
3+
-- Version 0.9.2 - 2025/07/29
44
55
In early versions of SOAR mode in Ardupilot, which I collaborated on with
66
the author, when the glider exited THERMAL mode the heading pointed
@@ -124,7 +124,7 @@ Script Parameters (SNAV_*)
124124

125125
--[[ SCRIPT INITIALIZATION ]]--
126126

127-
math.randomseed(tonumber(tostring(millis())))
127+
math.randomseed(tonumber(tostring(millis() or 0)))
128128

129129
-- Enums for GCS message severity and script internal state
130130
local MAV_SEVERITY = {
@@ -480,18 +480,16 @@ local function calculate_bearing(lat1, lon1, lat2, lon2)
480480
return (brng + 360) % 360
481481
end
482482

483-
if not location_offset then
484-
function snav_snav_location_offset(lat, lon, brng, dist)
485-
local R = 6371000
486-
local lat_rad, lon_rad = math.rad(lat), math.rad(lon)
487-
local brng_rad = math.rad(brng)
488-
local new_lat_rad = math.asin(math.sin(lat_rad) * math.cos(dist / R) + math.cos(lat_rad) * math.sin(dist / R) * math.cos(brng_rad))
489-
local new_lon_rad = lon_rad + atan2_safe(math.sin(brng_rad) * math.sin(dist / R) * math.cos(lat_rad), math.cos(dist / R) - math.sin(lat_rad) * math.sin(new_lat_rad))
490-
local new_loc = Location()
491-
new_loc:lat(math.floor(math.deg(new_lat_rad) * 1e7 + 0.5))
492-
new_loc:lng(math.floor(math.deg(new_lon_rad) * 1e7 + 0.5))
493-
return new_loc
494-
end
483+
local function location_offset(lat, lon, brng, dist)
484+
local R = 6371000
485+
local lat_rad, lon_rad = math.rad(lat), math.rad(lon)
486+
local brng_rad = math.rad(brng)
487+
local new_lat_rad = math.asin(math.sin(lat_rad) * math.cos(dist / R) + math.cos(lat_rad) * math.sin(dist / R) * math.cos(brng_rad))
488+
local new_lon_rad = lon_rad + atan2_safe(math.sin(brng_rad) * math.sin(dist / R) * math.cos(lat_rad), math.cos(dist / R) - math.sin(lat_rad) * math.sin(new_lat_rad))
489+
local new_loc = Location()
490+
new_loc:lat(math.floor(math.deg(new_lat_rad) * 1e7 + 0.5))
491+
new_loc:lng(math.floor(math.deg(new_lon_rad) * 1e7 + 0.5))
492+
return new_loc
495493
end
496494

497495
-- Point-in-polygon check algorithm
@@ -663,8 +661,8 @@ local function manage_grid_initialization()
663661
local max_dist = p_max_dist:get() or 500
664662
local center_lat, center_lon = active_center:lat()/1e7, active_center:lng()/1e7
665663
local corner_dist = max_dist * 1.4142
666-
local sw_corner_loc = snav_snav_location_offset(center_lat, center_lon, 225, corner_dist)
667-
local ne_corner_loc = snav_snav_location_offset(center_lat, center_lon, 45, corner_dist)
664+
local sw_corner_loc = location_offset(center_lat, center_lon, 225, corner_dist)
665+
local ne_corner_loc = location_offset(center_lat, center_lon, 45, corner_dist)
668666
SoarNavGlobals.grid_bounds = {
669667
min_lat = sw_corner_loc:lat()/1e7, max_lat = ne_corner_loc:lat()/1e7,
670668
min_lon = sw_corner_loc:lng()/1e7, max_lon = ne_corner_loc:lng()/1e7
@@ -831,7 +829,7 @@ local function stop_and_record_thermal()
831829
local base_comp_time = safe_get(p_wind_comp, 60)
832830
local adaptive_comp_time = base_comp_time * math.max(0.5, math.min(2.0, avg_strength / 1.5))
833831
local offset_dist = wind_vel * adaptive_comp_time
834-
local corrected_loc = snav_snav_location_offset(hotspot_lat, hotspot_lon, upwind_bearing, offset_dist)
832+
local corrected_loc = location_offset(hotspot_lat, hotspot_lon, upwind_bearing, offset_dist)
835833
if corrected_loc then
836834
hotspot_lat, hotspot_lon = corrected_loc:lat()/1e7, corrected_loc:lng()/1e7
837835
end
@@ -983,7 +981,7 @@ end
983981

984982
-- Generates a random waypoint, ensuring it's inside the defined area
985983
local function generate_target_around_point(center_lat, center_lon, radius_m)
986-
local target_loc = snav_snav_location_offset(center_lat, center_lon, math.random() * 360, math.sqrt(math.random()) * radius_m)
984+
local target_loc = location_offset(center_lat, center_lon, math.random() * 360, math.sqrt(math.random()) * radius_m)
987985
if not target_loc then return nil, nil end
988986
local candidate_lat, candidate_lon = target_loc:lat()/1e7, target_loc:lng()/1e7
989987
local active_center = get_active_center_location()
@@ -1134,7 +1132,7 @@ local function search_for_new_waypoint()
11341132
local wind_dir_bearing = (math.deg(wind_heading_rad) + 180 + 360) % 360
11351133
local drift_factor = math.min(SoarNavConstants.MAX_DRIFT_FACTOR, age_s / SoarNavConstants.MAX_DRIFT_AGE_S)
11361134
drift_dist = wind_vel * age_s * drift_factor
1137-
local drifted_loc = snav_snav_location_offset(center_lat, center_lon, wind_dir_bearing, drift_dist)
1135+
local drifted_loc = location_offset(center_lat, center_lon, wind_dir_bearing, drift_dist)
11381136
if drifted_loc then
11391137
center_lat = drifted_loc:lat() / 1e7
11401138
center_lon = drifted_loc:lng() / 1e7
@@ -1163,7 +1161,7 @@ local function search_for_new_waypoint()
11631161
local max_dist = safe_get(p_max_dist, 500)
11641162
local rand_dist = math.sqrt(math.random()) * max_dist
11651163
local rand_bearing = math.random() * 360
1166-
local fallback_loc = snav_snav_location_offset(center_point_lat, center_point_lon, rand_bearing, rand_dist)
1164+
local fallback_loc = location_offset(center_point_lat, center_point_lon, rand_bearing, rand_dist)
11671165
if fallback_loc then
11681166
SoarNavGlobals.target_lat, SoarNavGlobals.target_lon = fallback_loc:lat()/1e7, fallback_loc:lng()/1e7
11691167
new_wp_found = true
@@ -1391,12 +1389,14 @@ update_body = function()
13911389
end
13921390
end
13931391
local rc_val = 0
1394-
if SoarNavGlobals.detected_soaring_rc_channel then rc_val = rc:get_pwm(SoarNavGlobals.detected_soaring_rc_channel) end
1395-
local script_switch_high = rc_val and rc_val >= SoarNavConstants.rc_thresh_high
1392+
if SoarNavGlobals.detected_soaring_rc_channel then
1393+
rc_val = rc:get_pwm(SoarNavGlobals.detected_soaring_rc_channel) or 0
1394+
end
1395+
local script_switch_high = rc_val >= SoarNavConstants.rc_thresh_high
13961396
local home = ahrs:get_home()
13971397
local dist_from_home_3d = ahrs:get_relative_position_NED_home()
13981398
local can_navigate = false
1399-
if arming:is_armed() and script_switch_high and (current_mode == SoarNavConstants.mode_fbwb or current_mode == SoarNavConstants.mode_cruise) and home and dist_from_home_3d and ahrs:get_yaw() and SoarNavGlobals.grid_initialized then
1399+
if arming:is_armed() and script_switch_high and (current_mode == SoarNavConstants.mode_fbwb or current_mode == SoarNavConstants.mode_cruise) and home and dist_from_home_3d and ahrs:get_yaw_rad() and SoarNavGlobals.grid_initialized then
14001400
local min_alt = safe_get(p_soar_alt_min, 40)
14011401
local current_alt = -dist_from_home_3d:z()
14021402
if SoarNavGlobals.script_state == SCRIPT_STATE.NAVIGATING or SoarNavGlobals.script_state == SCRIPT_STATE.THERMAL_PAUSE then
@@ -1463,7 +1463,7 @@ update_body = function()
14631463
log_gcs(MAV_SEVERITY.INFO, 1, string.format("Stuck detected. Repositioning upwind, adaptive distance: %.0fm", repo_dist_m))
14641464
local wind_heading_rad = atan2_safe(wind_vec:y(), wind_vec:x())
14651465
local upwind_bearing = (math.deg(wind_heading_rad) + 180 + 360) % 360
1466-
local repo_loc = snav_snav_location_offset(current_loc:lat()/1e7, current_loc:lng()/1e7, upwind_bearing, repo_dist_m)
1466+
local repo_loc = location_offset(current_loc:lat()/1e7, current_loc:lng()/1e7, upwind_bearing, repo_dist_m)
14671467
if repo_loc then
14681468
SoarNavGlobals.target_lat = repo_loc:lat()/1e7
14691469
SoarNavGlobals.target_lon = repo_loc:lng()/1e7
@@ -1507,7 +1507,7 @@ update_body = function()
15071507
end
15081508
local curr_lat, curr_lon = loc:lat()/1e7, loc:lng()/1e7
15091509
local target_heading = calculate_bearing(curr_lat, curr_lon, SoarNavGlobals.target_lat, SoarNavGlobals.target_lon)
1510-
local current_heading = math.deg(ahrs:get_yaw())
1510+
local current_heading = math.deg(ahrs:get_yaw_rad())
15111511
local heading_error = (target_heading - current_heading + 540) % 360 - 180
15121512
local last_grid_update_num = tonumber(tostring(SoarNavGlobals.last_grid_update_ms))
15131513
if last_grid_update_num == 0 or (current_time_num - last_grid_update_num) > SoarNavConstants.grid_update_interval_ms then

0 commit comments

Comments
 (0)