Skip to content

Commit

Permalink
Use Plane for Waypoints.
Browse files Browse the repository at this point in the history
  • Loading branch information
PerMalmberg committed Dec 4, 2023
1 parent 65a475b commit 045e9a5
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 41 deletions.
2 changes: 1 addition & 1 deletion e/lib
2 changes: 1 addition & 1 deletion src/flight/AxisControl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ function AxisControl.New(axis)
---@param target Vec3
function s.SetTarget(target)
if target == nil then
s:Disable()
s.Disable()
else
targetCoordinate = target
end
Expand Down
68 changes: 32 additions & 36 deletions src/flight/Waypoint.lua
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
require("abstraction/Vehicle")
local si = require("Singletons")
local calc, universe = si.calc, si.universe
local Ternary, max, abs = calc.Ternary, math.max, math.abs
local si = require("Singletons")
local Plane = require("math/Plane")
local calc, universe = si.calc, si.universe
local Ternary, max, abs, BetweenOrEqual = calc.Ternary, math.max, math.abs, calc.BetweenOrEqual

---@enum WPReachMode
WPReachMode = {
WPReachMode = {
ENTRY = 1,
EXIT = 2
}
Expand Down Expand Up @@ -43,7 +44,8 @@ Waypoint.__index = Waypoint
-- we don't get the point behind us and start turning around and also reduces oscilliating yaw.
local directionMargin = 1000
Waypoint.DirectionMargin = directionMargin
local pathAlignmentAngleLimit, pathAlignmentDistanceLimit, pitchAlignmentThrustLimiter, autoPitch = 0, 0, 0, false
local pathAlignmentAngleLimit, pathAlignmentDistanceLimit, pitchAlignmentThrustLimiter, autoPitch, gravPlane =
0, 0, 0, false, Plane.NewByVertialReference()

---@param angle number
function Waypoint.SetAlignmentAngleLimit(angle)
Expand Down Expand Up @@ -73,22 +75,24 @@ end
function Waypoint.New(destination, finalSpeed, maxSpeed, margin, pathAlignmentDistanceLimitFromSurface)
maxSpeed = Ternary(finalSpeed > maxSpeed and maxSpeed > 0, finalSpeed, maxSpeed) -- Guard against bad settings.
local yawLockDir = nil ---@type Vec3|nil
local lastInRoute, forceUpAlongVerticalRef, verticalUp, useAutoPitch = false, false, Vec3.zero, autoPitch

local lastInRoute, forceUpAlongVerticalRef, currentUp, useAutoPitch = false, false, Vec3.zero, autoPitch
local upPlane = Plane.New(function()
return currentUp
end)
local s = {}

---Gets the vertical up reference to use
---@param prev Waypoint Previous waypoint
---@return Vec3
local function getVerticalUpReference(prev)
local function getCurrentUp(prev)
-- When next waypoint is nearly aligned with -gravity, use the line between them as the vertical reference instead to make following the path more exact.
local vertUp = -universe.VerticalReferenceVector()
local gravUp = gravPlane.Up()

if forceUpAlongVerticalRef then
return vertUp
return gravUp
end

local selectedRef = vertUp
local selectedRef = gravUp

local pathDirection = (destination - prev.Destination()):Normalize()
local body = universe.ClosestBody(Current())
Expand All @@ -106,11 +110,11 @@ function Waypoint.New(destination, finalSpeed, maxSpeed, margin, pathAlignmentDi
-- Disable auto pitch when tilting along the path
useAutoPitch = false
elseif pathAlignmentAngleLimit > 0 then -- if zero, it means the alignment is disabled
local sameDir = vertUp:Dot(pathDirection) > 0 -- Same direction?
if sameDir and vertUp:AngleToDeg(pathDirection) < pathAlignmentAngleLimit then
local sameDir = gravUp:Dot(pathDirection) > 0 -- Same direction?
if sameDir and gravUp:AngleToDeg(pathDirection) < pathAlignmentAngleLimit then
-- If we're more aligned to the path than the threshold, then align to the path
selectedRef = pathDirection
elseif not sameDir and vertUp:AngleToDeg(-pathDirection) < pathAlignmentAngleLimit then
elseif not sameDir and gravUp:AngleToDeg(-pathDirection) < pathAlignmentAngleLimit then
-- Don't flip upside down
selectedRef = -pathDirection
end
Expand Down Expand Up @@ -204,50 +208,42 @@ function Waypoint.New(destination, finalSpeed, maxSpeed, margin, pathAlignmentDi

---@param prev Waypoint
function s.PreCalc(prev)
verticalUp = getVerticalUpReference(prev)
currentUp = getCurrentUp(prev)
end

function s.ForceUpAlongVerticalRef()
forceUpAlongVerticalRef = true
end

---@param prev Waypoint
---@return Vec3
local function rollTopsideAwayFromVerticalReference(prev)
return Current() + verticalUp * directionMargin
end

---@param prev Waypoint
local function pitchKeepOrtogonalToVerticalRef(prev)
local forward = verticalUp:Cross(Right())
local right = forward:Cross(verticalUp)
return calc.ProjectPointOnPlane(right, Current(), Current() + forward * directionMargin)
local function pitchKeepOrtogonalToUp()
return calc.ProjectPointOnPlane(upPlane.Right(), Current(), Current() + upPlane.Forward() * directionMargin)
end

---@param prev Waypoint
---@return Vec3|nil
function s.Roll(prev)
return rollTopsideAwayFromVerticalReference(prev)
return calc.ProjectPointOnPlane(upPlane.Forward(), Current(), Current() + upPlane.Up() * directionMargin)
end

---@param prev Waypoint
---@return Vec3|nil
function s.Pitch(prev)
if useAutoPitch then
local moveDir, angleToVert, forward = Velocity():Normalize(), verticalUp:AngleToDeg(s.DirectionTo()),
verticalUp:Cross(Right())
local moveDir, forward = Velocity():Normalize(), upPlane.Forward()

if s.DistanceTo() > 10 and Velocity():Len() > calc.Kph2Mps(50)
and moveDir:AngleToDeg(s.DirectionTo()) <= calc.Clamp(pitchAlignmentThrustLimiter * 10, pitchAlignmentThrustLimiter, 45) --
and angleToVert > 15 and angleToVert < 180 - 15 -- Not going vertically
and forward:Dot(s.DirectionTo()) > 0 -- Not reversing
-- Not going vertically
and BetweenOrEqual(gravPlane.Up():AngleToDeg(s.DirectionTo()), 15, 180 - 15)
-- Not reversing or strafing
and BetweenOrEqual(forward:AngleToDeg(s.DirectionTo()), 0, 75)
then
local right = forward:Cross(verticalUp)
local target = Current() + moveDir * directionMargin
return calc.ProjectPointOnPlane(right, Current(), target)
return calc.ProjectPointOnPlane(upPlane.Right(), Current(), target)
end
end

return pitchKeepOrtogonalToVerticalRef(prev)
return pitchKeepOrtogonalToUp()
end

---@param prev Waypoint
Expand All @@ -266,12 +262,12 @@ function Waypoint.New(destination, finalSpeed, maxSpeed, margin, pathAlignmentDi
end

-- To prevent spinning, lock yaw if we're aligning to vertical up
if not yawLockDir and abs(dir:Dot(verticalUp)) > 0.9 then
if not yawLockDir and abs(dir:Dot(currentUp)) > 0.9 then
s.LockYawTo(Forward(), false)
dir = Forward()
end

return calc.ProjectPointOnPlane(verticalUp, Current(), Current() + dir * directionMargin)
return calc.ProjectPointOnPlane(currentUp, Current(), Current() + dir * directionMargin)
end

return setmetatable(s, Waypoint)
Expand Down
5 changes: 2 additions & 3 deletions src/hud/Hud.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require("GlobalTypes")
local s = require("Singletons")
local log, pub, input, calc, Template = s.log, s.pub, s.input, s.calc, require("Template")
local si = require("Singletons")
local log, pub, input, calc, Template = si.log, si.pub, si.input, si.calc, require("Template")
local hudTemplate = library.embedFile("hud.html")

local updateInterval = 0.3
Expand All @@ -13,7 +13,6 @@ local updateInterval = 0.3
local Hud = {}
Hud.__index = Hud


---@return Hud
function Hud.New()
local s = {}
Expand Down

0 comments on commit 045e9a5

Please sign in to comment.