mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
navygroup
- into wind
This commit is contained in:
parent
153ef7cd08
commit
7453a6c55d
@ -180,7 +180,6 @@ end
|
|||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
--- NAVFIX class.
|
--- NAVFIX class.
|
||||||
-- @type NAVFIX
|
-- @type NAVFIX
|
||||||
-- @field #string ClassName Name of the class.
|
-- @field #string ClassName Name of the class.
|
||||||
@ -283,59 +282,6 @@ end
|
|||||||
-- User Functions
|
-- User Functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- Set minimum altitude.
|
|
||||||
-- @param #NAVFIX self
|
|
||||||
-- @param #number Altitude Min altitude in feet.
|
|
||||||
-- @return #NAVFIX self
|
|
||||||
function NAVFIX:SetAltMin(Altitude)
|
|
||||||
|
|
||||||
self.altMin=Altitude
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set maximum altitude.
|
|
||||||
-- @param #NAVFIX self
|
|
||||||
-- @param #number Altitude Max altitude in feet.
|
|
||||||
-- @return #NAVFIX self
|
|
||||||
function NAVFIX:SetAltMax(Altitude)
|
|
||||||
|
|
||||||
self.altMax=Altitude
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Set mandatory altitude (min alt = max alt).
|
|
||||||
-- @param #NAVFIX self
|
|
||||||
-- @param #number Altitude Altitude in feet.
|
|
||||||
-- @return #NAVFIX self
|
|
||||||
function NAVFIX:SetAltMandatory(Altitude)
|
|
||||||
|
|
||||||
self.altMin=Altitude
|
|
||||||
self.altMax=Altitude
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set whether this fix is compulsory.
|
|
||||||
-- @param #NAVFIX self
|
|
||||||
-- @param #boolean Compulsory If `true`, this is a compusory fix. If `false` or nil, it is non-compulsory.
|
|
||||||
-- @return #NAVFIX self
|
|
||||||
function NAVFIX:SetCompulsory(Compulsory)
|
|
||||||
self.isCompulsory=Compulsory
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set whether this is a fly-over fix fix.
|
|
||||||
-- @param #NAVFIX self
|
|
||||||
-- @param #boolean FlyOver If `true`, this is a fly over fix. If `false` or nil, it is not.
|
|
||||||
-- @return #NAVFIX self
|
|
||||||
function NAVFIX:SetFlyOver(FlyOver)
|
|
||||||
self.isFlyover=FlyOver
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set whether this is the intermediate fix (IF).
|
--- Set whether this is the intermediate fix (IF).
|
||||||
-- @param #NAVFIX self
|
-- @param #NAVFIX self
|
||||||
-- @param #boolean IntermediateFix If `true`, this is an intermediate fix.
|
-- @param #boolean IntermediateFix If `true`, this is an intermediate fix.
|
||||||
@ -378,24 +324,6 @@ function NAVFIX:SetMissedApproachFix(MissedApproachFix)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Get the altitude in feet MSL.
|
|
||||||
-- @param #NAVFIX self
|
|
||||||
-- @return #number Altitude in feet MSL. Can be `nil`, if neither min nor max altitudes have beeen set.
|
|
||||||
function NAVFIX:GetAltitude()
|
|
||||||
|
|
||||||
local alt=nil
|
|
||||||
if self.altMin and self.altMax then
|
|
||||||
alt=math.random(self.altMin, self.altMax)
|
|
||||||
elseif self.altMin then
|
|
||||||
alt=self.altMin
|
|
||||||
elseif self.altMax then
|
|
||||||
alt=self.altMax
|
|
||||||
end
|
|
||||||
|
|
||||||
return alt
|
|
||||||
end
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Private Functions
|
-- Private Functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -438,6 +366,9 @@ end
|
|||||||
-- @field #string name Name of the point.
|
-- @field #string name Name of the point.
|
||||||
-- @field Core.Vector#VECTOR vector Position vector of the fix.
|
-- @field Core.Vector#VECTOR vector Position vector of the fix.
|
||||||
-- @field Wrapper.Marker#MARKER marker Marker on F10 map.
|
-- @field Wrapper.Marker#MARKER marker Marker on F10 map.
|
||||||
|
-- @field #number altMin Minimum altitude in meters.
|
||||||
|
-- @field #number altMax Maximum altitude in meters.
|
||||||
|
--
|
||||||
-- @field #boolean isCompulsory Is this a compulsory fix.
|
-- @field #boolean isCompulsory Is this a compulsory fix.
|
||||||
--
|
--
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
@ -489,11 +420,16 @@ function NAVPOINT:NewFromVector(Name, Vector)
|
|||||||
-- Inherit everything from BASE class.
|
-- Inherit everything from BASE class.
|
||||||
self=BASE:Inherit(self, BASE:New()) -- #NAVFIX
|
self=BASE:Inherit(self, BASE:New()) -- #NAVFIX
|
||||||
|
|
||||||
|
-- Vector of point.
|
||||||
self.vector=Vector
|
self.vector=Vector
|
||||||
|
|
||||||
|
-- Name of point.
|
||||||
self.name=Name
|
self.name=Name
|
||||||
|
|
||||||
--self.marker=MARKER:New(Coordinate, self:_GetMarkerText())
|
-- Marker on F10.
|
||||||
|
self.marker=MARKER:New(Vector:GetCoordinate(true), self:_GetMarkerText())
|
||||||
|
|
||||||
|
|
||||||
--self.marker:ToAll()
|
--self.marker:ToAll()
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@ -529,9 +465,9 @@ function NAVPOINT:NewFromNavPoint(Name, NavPoint, Distance, Bearing, Reciprocal)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Translate.
|
-- Translate.
|
||||||
local coord=NavPoint.coordinate:Translate(UTILS.NMToMeters(Distance), Bearing)
|
local Vector=NavPoint.vector:Translate(UTILS.NMToMeters(Distance), Bearing)
|
||||||
|
|
||||||
local self=NavPoint:NewFromCoordinate(Name, coord)
|
self=NavPoint:NewFromVector(Name, Vector)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -540,13 +476,106 @@ end
|
|||||||
-- User Functions
|
-- User Functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- No user functions yet.
|
--- Set minimum altitude.
|
||||||
|
-- @param #NAVPOINT self
|
||||||
|
-- @param #number Altitude Min altitude in feet.
|
||||||
|
-- @return #NAVPOINT self
|
||||||
|
function NAVPOINT:SetAltMin(Altitude)
|
||||||
|
|
||||||
|
self.altMin=Altitude
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set maximum altitude.
|
||||||
|
-- @param #NAVPOINT self
|
||||||
|
-- @param #number Altitude Max altitude in feet.
|
||||||
|
-- @return #NAVPOINT self
|
||||||
|
function NAVPOINT:SetAltMax(Altitude)
|
||||||
|
|
||||||
|
self.altMax=Altitude
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set mandatory altitude (min alt = max alt).
|
||||||
|
-- @param #NAVPOINT self
|
||||||
|
-- @param #number Altitude Altitude in feet.
|
||||||
|
-- @return #NAVPOINT self
|
||||||
|
function NAVPOINT:SetAltMandatory(Altitude)
|
||||||
|
|
||||||
|
self.altMin=Altitude
|
||||||
|
self.altMax=Altitude
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set whether this fix is compulsory.
|
||||||
|
-- @param #NAVPOINT self
|
||||||
|
-- @param #boolean Compulsory If `true`, this is a compusory fix. If `false` or nil, it is non-compulsory.
|
||||||
|
-- @return #NAVPOINT self
|
||||||
|
function NAVPOINT:SetCompulsory(Compulsory)
|
||||||
|
self.isCompulsory=Compulsory
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set whether this is a fly-over fix fix.
|
||||||
|
-- @param #NAVPOINT self
|
||||||
|
-- @param #boolean FlyOver If `true`, this is a fly over fix. If `false` or nil, it is not.
|
||||||
|
-- @return #NAVPOINT self
|
||||||
|
function NAVPOINT:SetFlyOver(FlyOver)
|
||||||
|
self.isFlyover=FlyOver
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the altitude in feet MSL.
|
||||||
|
-- @param #NAVPOINT self
|
||||||
|
-- @return #number Altitude in feet MSL. Can be `nil`, if neither min nor max altitudes have beeen set.
|
||||||
|
function NAVPOINT:GetAltitude()
|
||||||
|
|
||||||
|
local alt=nil
|
||||||
|
if self.altMin and self.altMax then
|
||||||
|
alt=math.random(self.altMin, self.altMax)
|
||||||
|
elseif self.altMin then
|
||||||
|
alt=self.altMin
|
||||||
|
elseif self.altMax then
|
||||||
|
alt=self.altMax
|
||||||
|
end
|
||||||
|
|
||||||
|
return alt
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Private Functions
|
-- Private Functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- No private functions yet.
|
--- Get text displayed in the F10 marker.
|
||||||
|
-- @param #NAVPOINT self
|
||||||
|
-- @return #string Marker text.
|
||||||
|
function NAVPOINT:_GetMarkerText()
|
||||||
|
|
||||||
|
local altmin=self.altMin and tostring(self.altMin) or ""
|
||||||
|
local altmax=self.altMax and tostring(self.altMax) or ""
|
||||||
|
local speedmin=self.speedMin and tostring(self.speedMin) or ""
|
||||||
|
local speedmax=self.speedMax and tostring(self.speedMax) or ""
|
||||||
|
|
||||||
|
|
||||||
|
local text=string.format("NAVPOINT %s", self.name)
|
||||||
|
if self.isIAF then
|
||||||
|
text=text..string.format(" (IAF)")
|
||||||
|
end
|
||||||
|
if self.isIF then
|
||||||
|
text=text..string.format(" (IF)")
|
||||||
|
end
|
||||||
|
text=text..string.format("\nAltitude: %s - %s", altmin, altmax)
|
||||||
|
text=text..string.format("\nSpeed: %s - %s", speedmin, speedmax)
|
||||||
|
text=text..string.format("\nCompulsory: %s", tostring(self.isCompulsory))
|
||||||
|
text=text..string.format("\nFly Over: %s", tostring(self.isFlyover))
|
||||||
|
|
||||||
|
return text
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -1277,25 +1277,20 @@ end
|
|||||||
-- @param #NAVYGROUP.IntoWind Into wind parameters.
|
-- @param #NAVYGROUP.IntoWind Into wind parameters.
|
||||||
function NAVYGROUP:onafterTurnIntoWind(From, Event, To, IntoWind)
|
function NAVYGROUP:onafterTurnIntoWind(From, Event, To, IntoWind)
|
||||||
|
|
||||||
IntoWind.Heading=self:GetHeadingIntoWind(IntoWind.Offset)
|
-- Calculate heading and speed of ship.
|
||||||
|
local heading, speed=self:GetHeadingIntoWind(IntoWind.Offset, IntoWind.Speed)
|
||||||
|
|
||||||
|
IntoWind.Heading=heading
|
||||||
IntoWind.Open=true
|
IntoWind.Open=true
|
||||||
|
|
||||||
|
-- Get coordinate.
|
||||||
IntoWind.Coordinate=self:GetCoordinate(true)
|
IntoWind.Coordinate=self:GetCoordinate(true)
|
||||||
|
|
||||||
|
-- Set current into wind parameters.
|
||||||
self.intowind=IntoWind
|
self.intowind=IntoWind
|
||||||
|
|
||||||
-- Wind speed in m/s.
|
|
||||||
local _,vwind=self:GetWind()
|
|
||||||
|
|
||||||
-- Convert to knots.
|
|
||||||
vwind=UTILS.MpsToKnots(vwind)
|
|
||||||
|
|
||||||
-- Speed of carrier relative to wind but at least 4 knots.
|
|
||||||
local speed=math.max(IntoWind.Speed-vwind, 4)
|
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T(self.lid..string.format("Steaming into wind: Heading=%03d Speed=%.1f Vwind=%.1f Vtot=%.1f knots, Tstart=%d Tstop=%d", IntoWind.Heading, speed, vwind, speed+vwind, IntoWind.Tstart, IntoWind.Tstop))
|
self:T(self.lid..string.format("Steaming into wind: Heading=%03d Speed=%.1f, Tstart=%d Tstop=%d", IntoWind.Heading, speed, IntoWind.Tstart, IntoWind.Tstop))
|
||||||
|
|
||||||
local distance=UTILS.NMToMeters(1000)
|
local distance=UTILS.NMToMeters(1000)
|
||||||
|
|
||||||
@ -2072,7 +2067,7 @@ end
|
|||||||
-- @param #NAVYGROUP self
|
-- @param #NAVYGROUP self
|
||||||
-- @param #number Offset Offset angle in degrees, e.g. to account for an angled runway.
|
-- @param #number Offset Offset angle in degrees, e.g. to account for an angled runway.
|
||||||
-- @return #number Carrier heading in degrees.
|
-- @return #number Carrier heading in degrees.
|
||||||
function NAVYGROUP:GetHeadingIntoWind(Offset)
|
function NAVYGROUP:GetHeadingIntoWind_old(Offset)
|
||||||
|
|
||||||
Offset=Offset or 0
|
Offset=Offset or 0
|
||||||
|
|
||||||
@ -2086,15 +2081,101 @@ function NAVYGROUP:GetHeadingIntoWind(Offset)
|
|||||||
if vwind<0.1 then
|
if vwind<0.1 then
|
||||||
intowind=self:GetHeading()
|
intowind=self:GetHeading()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Adjust negative values.
|
-- Adjust negative values.
|
||||||
if intowind<0 then
|
if intowind<0 then
|
||||||
intowind=intowind+360
|
intowind=intowind+360
|
||||||
end
|
end
|
||||||
|
|
||||||
return intowind
|
return intowind
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get heading of group into the wind. This minimizes the cross wind for an angled runway.
|
||||||
|
-- Implementation based on [Mags & Bami](https://magwo.github.io/carrier-cruise/) work.
|
||||||
|
-- @param #NAVYGROUP self
|
||||||
|
-- @param #number Offset Offset angle in degrees, e.g. to account for an angled runway.
|
||||||
|
-- @param #number vdeck Desired wind speed on deck in Knots.
|
||||||
|
-- @return #number Carrier heading in degrees.
|
||||||
|
function NAVYGROUP:GetHeadingIntoWind(Offset, vdeck)
|
||||||
|
|
||||||
|
-- Default offset angle.
|
||||||
|
Offset=Offset or 0
|
||||||
|
|
||||||
|
-- Get direction the wind is blowing from.
|
||||||
|
local windfrom, vwind=self:GetWind()
|
||||||
|
|
||||||
|
-- Convert wind speed to knots.
|
||||||
|
vwind=UTILS.MpsToKnots(vwind)
|
||||||
|
|
||||||
|
-- Wind to in knots.
|
||||||
|
local windto=(windfrom+180)%360
|
||||||
|
|
||||||
|
-- Offset angle in rad.
|
||||||
|
local alpha=math.rad(Offset)
|
||||||
|
|
||||||
|
-- Ships min/max speed.
|
||||||
|
local Vmin=4
|
||||||
|
local Vmax=UTILS.KmphToKnots(self.speedMax)
|
||||||
|
|
||||||
|
-- Constant.
|
||||||
|
local C = math.sqrt(math.cos(alpha)^2 / math.sin(alpha)^2 + 1)
|
||||||
|
|
||||||
|
|
||||||
|
-- Upper limit of desired speed due to max boat speed.
|
||||||
|
local vdeckMax=vwind + math.cos(alpha) * Vmax
|
||||||
|
|
||||||
|
-- Lower limit of desired speed due to min boat speed.
|
||||||
|
local vdeckMin=vwind + math.cos(alpha) * Vmin
|
||||||
|
|
||||||
|
|
||||||
|
-- Speed of ship so it matches the desired speed.
|
||||||
|
local v
|
||||||
|
|
||||||
|
-- Angle wrt. to wind TO-direction
|
||||||
|
local theta
|
||||||
|
|
||||||
|
if vdeck>vdeckMax then
|
||||||
|
-- Boat cannot go fast enough
|
||||||
|
|
||||||
|
-- Set max speed.
|
||||||
|
v=Vmax
|
||||||
|
|
||||||
|
-- Calculate theta.
|
||||||
|
theta = math.asin(v/(vwind*C)) - math.asin(-1/C)
|
||||||
|
|
||||||
|
elseif vdeck<vdeckMin then
|
||||||
|
-- Boat cannot go slow enought
|
||||||
|
|
||||||
|
-- Set min speed.
|
||||||
|
v=Vmin
|
||||||
|
|
||||||
|
-- Calculatge theta.
|
||||||
|
theta = math.asin(v/(vwind*C)) - math.asin(-1/C)
|
||||||
|
|
||||||
|
elseif vdeck*math.sin(alpha)>vwind then
|
||||||
|
-- Too little wind
|
||||||
|
|
||||||
|
-- Set theta to 90°
|
||||||
|
theta=math.pi/2
|
||||||
|
|
||||||
|
-- Set speed.
|
||||||
|
v = math.sqrt(vdeck^2 - vwind^2)
|
||||||
|
|
||||||
|
else
|
||||||
|
-- Normal case
|
||||||
|
theta = math.asin(vdeck * math.sin(alpha) / vwind)
|
||||||
|
v = vdeck * math.cos(alpha) - vwind * math.cos(theta)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Ship heading so cross wind is min for the given wind.
|
||||||
|
local intowind = (540 + (windto + math.deg(theta) )) % 360
|
||||||
|
|
||||||
|
return intowind, v
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Find free path to next waypoint.
|
--- Find free path to next waypoint.
|
||||||
-- @param #NAVYGROUP self
|
-- @param #NAVYGROUP self
|
||||||
-- @return #boolean If true, a path was found.
|
-- @return #boolean If true, a path was found.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user