diff --git a/Moose Development/Moose/Navigation/Point.lua b/Moose Development/Moose/Navigation/Point.lua index f9716109b..c96643308 100644 --- a/Moose Development/Moose/Navigation/Point.lua +++ b/Moose Development/Moose/Navigation/Point.lua @@ -20,175 +20,32 @@ -- @image NAVIGATION_Point.png ---- NAVAID class. --- @type NAVAID --- @field #string ClassName Name of the class. --- @field #number verbose Verbosity of output. --- @extends Core.Base#BASE - ---- *A fleet of British ships at war are the best negotiators.* -- Horatio Nelson --- --- === --- --- # The NAVAID Concept --- --- A NAVAID consists of one or multiple FLOTILLAs. These flotillas "live" in a WAREHOUSE that has a phyiscal struction (STATIC or UNIT) and can be captured or destroyed. --- --- # Basic Setup --- --- A new `NAVAID` object can be created with the @{#NAVAID.New}(`WarehouseName`, `FleetName`) function, where `WarehouseName` is the name of the static or unit object hosting the fleet --- and `FleetName` is the name you want to give the fleet. This must be *unique*! --- --- myFleet=NAVAID:New("myWarehouseName", "1st Fleet") --- myFleet:SetPortZone(ZonePort1stFleet) --- myFleet:Start() --- --- A fleet needs a *port zone*, which is set via the @{#NAVAID.SetPortZone}(`PortZone`) function. This is the zone where the naval assets are spawned and return to. --- --- Finally, the fleet needs to be started using the @{#NAVAID.Start}() function. If the fleet is not started, it will not process any requests. --- --- @field #NAVAID -NAVAID = { - ClassName = "NAVAID", - verbose = 0, -} - ---- Type of navaid --- @type NAVAID.Type --- @field #string VOR Very High Frequency Omnirange Station (VOR). --- @field #string NDB Non-Directional Beacon (NDB). --- @field #string DME Distance Measuring Equipment (DME). --- @field #string TACAN TACtical Air Navigation System (TACAN). --- @field #string LOC LOCalizer for horizontal guidance (LOC). -NAVAID.Type={ - VOR="VOR", - NDB="NDB", - DME="DME", - TACAN="TACAN", - LOC="Localizer" -} - ---- NAVAID class version. --- @field #string version -NAVAID.version="0.0.1" - -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- ToDo list -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - --- TODO: Add frequencies. Which unit MHz, kHz, Hz? --- TODO: Add radial function - -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- Constructor -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - ---- Create a new NAVAID class instance. --- @param #NAVAID self --- @param #string ZoneName Name of the zone to scan the scenery. --- @param #string SceneryName Name of the scenery object. --- @param #string Type Type of Navaid. --- @return #NAVAID self -function NAVAID:New(ZoneName, SceneryName, Type) - - -- Inherit everything from BASE class. - self=BASE:Inherit(self, BASE:New()) -- #NAVAID - - - self.zone=ZONE:FindByName(ZoneName) - - self.coordinate=self.zone:GetCoordinate() - - if SceneryName then - self.scenery=SCENERY:FindByNameInZone(SceneryName, ZoneName) - if not self.scenery then - self:E("ERROR: Could not find scenery object %s in zone %s", SceneryName, ZoneName) - end - end - - self.alias=string.format("%s %s %s", tostring(ZoneName), tostring(SceneryName), tostring(Type)) - - - -- Set some string id for output to DCS.log file. - self.lid=string.format("NAVAID %s | ", self.alias) - - self:I(self.lid..string.format("Created NAVAID!")) - - return self -end - -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- User Functions -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - ---- Set frequency. --- @param #NAVAID self --- @param #number Frequency Frequency in Hz. --- @return #NAVAID self -function NAVAID:SetFrequency(Frequency) - - self.frequency=Frequency - - return self -end - ---- Set channel. --- @param #NAVAID self --- @param #number Channel --- @param #string Band --- @return #NAVAID self -function NAVAID:SetChannel(Channel, Band) - - self.channel=Channel - self.band=Band - - return self -end - ---- Add marker the NAVAID on the F10 map. --- @param #NAVAID self --- @return #NAVAID self -function NAVAID:AddMarker() - - local text=string.format("I am a NAVAID!") - - self.markID=self.coordinate:MarkToAll(text, true) - - return self -end - ---- Remove marker of the NAVAID from the F10 map. --- @param #NAVAID self --- @return #NAVAID self -function NAVAID:DelMarker() - - if self.markID then - UTILS.RemoveMark(self.markID) - end - - return self -end - -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- Private Functions -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - --- Add private CLASS functions here. --- No private NAVAID functions yet. - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- NAVFIX class. -- @type NAVFIX --- @field #string ClassName Name of the class. --- @field #boolean isIAF Is initial approach fix (IAF). --- @field #boolean isIF Is intermediate fix (IF). --- @field #boolean isFAF Is final approach fix (FAF). --- @field #boolean isMAF Is missed approach fix (MAF). -- --- @extends Navigation.Point#NAVPOINT +-- @field #string ClassName Name of the class. +-- @field #number verbose Verbosity of output. +-- @field #string name Name of the point. +-- @field #string typePoint Type of the point, *e.g. "Intersection", "VOR", "Airport". +-- @field Core.Vector#VECTOR vector Position vector of the fix. +-- @field Wrapper.Marker#MARKER marker Marker on F10 map. +-- @field #number altMin Minimum altitude in meters. +-- @field #number altMax Maximum altitude in meters. +-- @field #number speedMin Minimum speed in knots. +-- @field #number speedMax Maximum speed in knots. +-- +-- @field #boolean isCompulsory Is this a compulsory fix. +-- @field #boolean isFlyover Is this a flyover fix (`true`) or turning point otherwise. +-- @field #boolean isFAF Is this a final approach fix. +-- @field #boolean isIAF Is this an initial approach fix. +-- @field #boolean isIF Is this an initial fix. +-- @field #boolean isMAF Is this an initial fix. +-- +-- @extends Core.Base#BASE --- *A fleet of British ships at war are the best negotiators.* -- Horatio Nelson -- @@ -198,11 +55,14 @@ end -- -- The NAVFIX class has a great concept! -- +-- A NAVFIX describes a geo position and can, *e.g.*, be part of a FLIGHTPLAN. It has a unique name and is of a certain type, *e.g.* "Intersection", "VOR", "Airbase" etc. +-- It can also have further properties as min/max altitudes and speeds that aircraft need to obey when they pass the point. +-- -- # Basic Setup -- -- A new `NAVFIX` object can be created with the @{#NAVFIX.New}() function. -- --- myTemplate=NAVFIX:New() +-- myNavPoint=NAVFIX:New() -- myTemplate:SetXYZ(X, Y, Z) -- -- This is how it works. @@ -210,18 +70,34 @@ end -- @field #NAVFIX NAVFIX = { ClassName = "NAVFIX", - verbose = 0, + verbose = 0, } ---- Type of navaid +--- Type of point. -- @type NAVFIX.Type --- @field #string VOR VOR --- @field #string NDB NDB +-- @field #string POINT Waypoint. +-- @field #string INTERSECTION Intersection of airway. +-- @field #string AIRPORT Airport. +-- @field #string VOR Very High Frequency Omnidirectional Range Station. +-- @field #string DME Distance Measuring Equipment. +-- @field #string NDB Non-Directional Beacon. +-- @field #string VORDME Combined VHF omnidirectional range (VOR) with a distance-measuring equipment (DME). +-- @field #string LOC Localizer. +-- @field #string ILS Instrument Landing System. +-- @field #string TACAN TACtical Air Navigation System (TACAN). NAVFIX.Type={ - VOR="VOR", + POINT="Point", + INTERSECTION="Intersection", + AIRPORT="Airport", NDB="NDB", + VOR="VOR", + DME="DME", + VORDME="VOR/DME", + LOC="Localizer", + ILS="ILS", + TACAN="TACAN" } - + --- NAVFIX class version. -- @field #string version NAVFIX.version="0.0.1" @@ -233,48 +109,123 @@ NAVFIX.version="0.0.1" -- TODO: A lot... ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- Constructor +-- Constructor(s) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---- Create a new NAVFIX class instance. +--- Create a new NAVFIX class instance from a given VECTOR. -- @param #NAVFIX self --- @param #string Name Name of the fix. Should be unique! --- @param Core.Point#COORDINATE Coordinate of the fix. +-- @param #string Name Name/ident of the point. Should be unique! +-- @param #string Type Type of the point. Default `NAVFIX.Type.POINT`. +-- @param Core.Vector#VECTOR Vector Position vector of the navpoint. -- @return #NAVFIX self -function NAVFIX:NewFromCoordinate(Name, Coordinate) +function NAVFIX:NewFromVector(Name, Type, Vector) - -- Inherit everything from SCENERY class. + -- Inherit everything from BASE class. self=BASE:Inherit(self, BASE:New()) -- #NAVFIX - self.coordinate=Coordinate + -- Vector of point. + self.vector=Vector + -- Name of point. self.name=Name - self.marker=MARKER:New(Coordinate, self:_GetMarkerText()) - self.marker:ToAll() + -- Type of the point. + self.typePoint=Type or NAVFIX.Type.POINT + + -- Marker on F10. + self.marker=MARKER:New(coord, self:_GetMarkerText()) + + -- Log ID string. + self.lid=string.format("NAVFIX %s [%s] | ", tostring(self.name), tostring(self.typePoint)) + + -- Debug info. + self:I(self.lid..string.format("Created NAVFIX")) return self end ---- Create a new NAVFIX class instance from a given NavAid. + +--- Create a new NAVFIX class instance from a given COORDINATE. -- @param #NAVFIX self -- @param #string Name Name of the fix. Should be unique! --- @param Navigation.NavFix#NAVFIX NavFix The navigation fix. --- @param #number Distance Distance in nautical miles. --- @param #number Bearing Bearing from the given NavFix to the newly created one. --- @param #boolean Reciprocal If `true` the reciprocal `Bearing` is taken so it specifies the direction from the new navfix to the given one. +-- @param #string Type Type of the point. Default `NAVFIX.Type.POINT`. +-- @param Core.Point#COORDINATE Coordinate Coordinate of the point. -- @return #NAVFIX self -function NAVFIX:NewFromNavFix(Name, NavFix, Distance, Bearing, Reciprocal) +function NAVFIX:NewFromCoordinate(Name, Type, Coordinate) - local coord=NavFix.coordinate + -- Create a VECTOR from the coordinate. + local Vector=VECTOR:NewFromVec(Coordinate) - local Angle=Bearing-90 - - local coord=NavFix.coordinate:Translate(UTILS.NMToMeters(Distance), Angle) - - local self=NAVFIX:NewFromCoordinate(coord, Name) + -- Create NAVFIX. + self=NAVFIX:NewFromVector(Name, Type, Vector) + return self +end + +--- Create a new NAVFIX instance from given latitude and longitude in degrees, minutes and seconds (DMS). +-- @param #NAVFIX self +-- @param #string Name Name of the fix. Should be unique! +-- @param #string Type Type of the point. Default `NAVFIX.Type.POINT`. +-- @param #string Latitude Latitude in DMS as string. +-- @param #string Longitude Longitude in DMS as string. +-- @return #NAVFIX self +function NAVFIX:NewFromLLDMS(Name, Type, Latitude, Longitude) + + -- Create a VECTOR from the coordinate. + local Vector=VECTOR:NewFromLLDMS(Latitude, Longitude) + + -- Create NAVFIX. + self=NAVFIX:NewFromVector(Name, Type, Vector) + + return self +end + +--- Create a new NAVFIX instance from given latitude and longitude in decimal degrees (DD). +-- @param #NAVFIX self +-- @param #string Name Name of the fix. Should be unique! +-- @param #string Type Type of the point. Default `NAVFIX.Type.POINT`. +-- @param #number Latitude Latitude in DD. +-- @param #number Longitude Longitude in DD. +-- @return #NAVFIX self +function NAVFIX:NewFromLLDD(Name, Type, Latitude, Longitude) + + -- Create a VECTOR from the coordinate. + local Vector=VECTOR:NewFromLLDD(Latitude, Longitude) + + -- Create NAVFIX. + self=NAVFIX:NewFromVector(Name, Type, Vector) + + return self +end + + +--- Create a new NAVFIX class instance relative to a given other NAVFIX. +-- You have to specify the distance and bearing from the new point to the given point. *E.g.*, for a distance of 5 NM and a bearing of 090° (West), the +-- new nav point is created 5 NM East of the given nav point. The reason is that this corresponts to convention used in most maps. +-- You can, however, use the `Reciprocal` switch to create the new point in the direction you specify. +-- @param #NAVFIX self +-- @param #string Name Name of the fix. Should be unique! +-- @param #string Type Type of navfix. +-- @param #NAVFIX NavFix The given/existing navigation fix relative to which the new fix is created. +-- @param #number Distance Distance from the given to the new point in nautical miles. +-- @param #number Bearing Bearing [Deg] from the new point to the given one. +-- @param #boolean Reciprocal If `true` the reciprocal `Bearing` is taken so it specifies the direction from the given point to the new one. +-- @return #NAVFIX self +function NAVFIX:NewFromNavFix(Name, Type, NavFix, Distance, Bearing, Reciprocal) + + -- Convert magnetic to true bearing by adding magnetic declination, e.g. mag. bearing 10°M ==> true bearing 16°M (for 6° variation on Caucasus map) + Bearing=Bearing+UTILS.GetMagneticDeclination() + + if Reciprocal then + Bearing=Bearing-180 + end + + -- Translate. + local Vector=NavFix.vector:Translate(UTILS.NMToMeters(Distance), Bearing, true) + + self=NAVFIX:NewFromVector(Name, Type, Vector) + return self end @@ -284,7 +235,6 @@ end --- Set whether this is the intermediate fix (IF). -- @param #NAVFIX self --- @param #boolean IntermediateFix If `true`, this is an intermediate fix. -- @return #NAVFIX self function NAVFIX:SetIntermediateFix(IntermediateFix) self.isIF=IntermediateFix @@ -324,6 +274,152 @@ function NAVFIX:SetMissedApproachFix(MissedApproachFix) return self end + +--- 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 minimum allowed speed at this fix. +-- @param #NAVFIX self +-- @param #number Speed Min speed in knots. +-- @return #NAVFIX self +function NAVFIX:SetSpeedMin(Speed) + + self.speedMin=Speed + + return self +end + +--- Set maximum allowed speed at this fix. +-- @param #NAVFIX self +-- @param #number Speed Max speed in knots. +-- @return #NAVFIX self +function NAVFIX:SetSpeedMax(Speed) + + self.speedMax=Speed + + return self +end + +--- Set mandatory speed (min speed = max speed) at this fix. +-- @param #NAVFIX self +-- @param #number Speed Mandatory speed in knots. +-- @return #NAVFIX self +function NAVFIX:SetSpeedMandatory(Speed) + + self.speedMin=Speed + self.speedMax=Speed + + 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 + + +--- Get the altitude in feet MSL. If min and max altitudes are set, it will return a random altitude between min and max. +-- @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 and self.altMin~=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 + + +--- Get the speed. If min and max speeds are set, it will return a random speed between min and max. +-- @param #NAVFIX self +-- @return #number Speed in knots. Can be `nil`, if neither min nor max speeds have beeen set. +function NAVFIX:GetSpeed() + + local speed=nil + if self.speedMin and self.speedMax and self.speedMin~=self.speedMax then + speed=math.random(self.speedMin, self.speedMax) + elseif self.speedMin then + speed=self.speedMin + elseif self.speedMax then + speed=self.speedMax + end + + return speed +end + + + +--- Add marker the NAVFIX on the F10 map. +-- @param #NAVFIX self +-- @return #NAVFIX self +function NAVFIX:MarkerShow() + + self.marker:ToAll() + + return self +end + +--- Remove marker of the NAVFIX from the F10 map. +-- @param #NAVFIX self +-- @return #NAVFIX self +function NAVFIX:MarkerRemove() + + self.marker:Remove() + + return self +end + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Private Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -346,195 +442,105 @@ function NAVFIX:_GetMarkerText() 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("\nAltitude [ft]: %s - %s", altmin, altmax) + text=text..string.format("\nSpeed [knots]: %s - %s", speedmin, speedmax) text=text..string.format("\nCompulsory: %s", tostring(self.isCompulsory)) - text=text..string.format("\nFly Over: %s", tostring(self.isFlyover)) + text=text..string.format("\nFly Over: %s", tostring(self.isFlyover)) return text end + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---- NAVPOINT class. --- @type NAVPOINT --- +--- NAVAID class. +-- @type NAVAID -- @field #string ClassName Name of the class. -- @field #number verbose Verbosity of output. --- @field #string name Name of the point. --- @field #string typePoint Type of the point, *e.g. "Intersection", "VOR", "Airport". --- @field Core.Vector#VECTOR vector Position vector of the fix. --- @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. --- --- @extends Core.Base#BASE +-- @extends Navigation.Point#NAVFIX --- *A fleet of British ships at war are the best negotiators.* -- Horatio Nelson -- -- === -- --- # The NAVPOINT Concept +-- # The NAVAID Concept -- --- The NAVPOINT class has a great concept! --- --- A NAVPOINT describes a geo position and can, *e.g.*, be part of a FLIGHTPLAN. It has a unique name and is of a certain type, *e.g.* "Intersection", "VOR", "Airbase" etc. --- It can also have further properties as min/max altitudes and speeds that aircraft need to obey when they pass the point. +-- A NAVAID consists of one or multiple FLOTILLAs. These flotillas "live" in a WAREHOUSE that has a phyiscal struction (STATIC or UNIT) and can be captured or destroyed. -- -- # Basic Setup -- --- A new `NAVPOINT` object can be created with the @{#NAVPOINT.New}() function. +-- A new `NAVAID` object can be created with the @{#NAVAID.New}(`WarehouseName`, `FleetName`) function, where `WarehouseName` is the name of the static or unit object hosting the fleet +-- and `FleetName` is the name you want to give the fleet. This must be *unique*! -- --- myNavPoint=NAVPOINT:New() --- myTemplate:SetXYZ(X, Y, Z) +-- myFleet=NAVAID:New("myWarehouseName", "1st Fleet") +-- myFleet:SetPortZone(ZonePort1stFleet) +-- myFleet:Start() -- --- This is how it works. +-- A fleet needs a *port zone*, which is set via the @{#NAVAID.SetPortZone}(`PortZone`) function. This is the zone where the naval assets are spawned and return to. +-- +-- Finally, the fleet needs to be started using the @{#NAVAID.Start}() function. If the fleet is not started, it will not process any requests. -- --- @field #NAVPOINT -NAVPOINT = { - ClassName = "NAVPOINT", - verbose = 0, +-- @field #NAVAID +NAVAID = { + ClassName = "NAVAID", + verbose = 0, } - ---- Type of point. --- @type NAVPOINT.Type --- @field #string VOR VOR --- @field #string NDB NDB -NAVPOINT.Type={ - POINT="Point", - INTERSECTION="Intersection", - AIRPORT="Airport", - VOR="VOR", - DME="DME", - VORDME="VOR/DME", - LOC="Localizer", - NDB="NDB", -} - ---- NAVPOINT class version. + +--- NAVAID class version. -- @field #string version -NAVPOINT.version="0.0.1" +NAVAID.version="0.0.1" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- ToDo list ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- TODO: A lot... +-- TODO: Add frequencies. Which unit MHz, kHz, Hz? +-- TODO: Add radial function ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- Constructor(s) +-- Constructor ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---- Create a new NAVPOINT class instance from a given VECTOR. --- @param #NAVPOINT self --- @param #string Name Name of the point. Should be unique! --- @param #string Type Type of the point. Default `NAVPOINT.Type.POINT`. --- @param Core.Vector#VECTOR Vector Position vector of the navpoint. --- @return #NAVPOINT self -function NAVPOINT:NewFromVector(Name, Type, Vector) +--- Create a new NAVAID class instance. +-- @param #NAVAID self +-- @param #string Name Name/ident of this navaid. +-- @param #string Type Type of the point. Default `NAVFIX.Type.POINT`. +-- @param #string ZoneName Name of the zone to scan the scenery. +-- @param #string SceneryName Name of the scenery object. +-- @return #NAVAID self +function NAVAID:NewFromScenery(Name, Type, ZoneName, SceneryName) - -- Inherit everything from BASE class. - self=BASE:Inherit(self, BASE:New()) -- #NAVFIX + -- Get the zone. + local zone=ZONE:FindByName(ZoneName) - -- Vector of point. - self.vector=Vector - - -- Name of point. - self.name=Name - - self.typePoint=Type or NAVPOINT.Type.POINT - - -- Marker on F10. - self.marker=MARKER:New(Vector:GetCoordinate(true), self:_GetMarkerText()) - - - --self.marker:ToAll() + -- Get coordinate. + local Coordinate=zone:GetCoordinate() - return self -end + -- Inherit everything from NAVFIX class. + self=BASE:Inherit(self, NAVFIX:NewFromCoordinate(Name, Type, Coordinate)) -- #NAVAID + -- Set zone. + self.zone=ZONE:FindByName(ZoneName) ---- Create a new NAVPOINT class instance from a given COORDINATE. --- @param #NAVPOINT self --- @param #string Name Name of the fix. Should be unique! --- @param #string Type Type of the point. Default `NAVPOINT.Type.POINT`. --- @param Core.Point#COORDINATE Coordinate Coordinate of the point. --- @return #NAVPOINT self -function NAVPOINT:NewFromCoordinate(Name, Type, Coordinate) - - -- Create a VECTOR from the coordinate. - local Vector=VECTOR:NewFromVec(Coordinate) - - -- Create NAVPOINT. - self=NAVPOINT:NewFromVector(Name, Type, Vector) - - return self -end - - ---- Create a new NAVPOINT instance from given latitude and longitude in degrees, minutes and seconds (DMS). --- @param #NAVPOINT self --- @param #string Name Name of the fix. Should be unique! --- @param #string Type Type of the point. Default `NAVPOINT.Type.POINT`. --- @param #string Latitude Latitude in DMS as string. --- @param #string Longitude Longitude in DMS as string. --- @return #NAVPOINT self -function NAVPOINT:NewFromLLDMS(Name, Type, Latitude, Longitude) - - -- Create a VECTOR from the coordinate. - local Vector=VECTOR:NewFromLLDMS(Latitude, Longitude) - - -- Create NAVPOINT. - self=NAVPOINT:NewFromVector(Name, Type, Vector) - - return self -end - ---- Create a new NAVPOINT instance from given latitude and longitude in decimal degrees (DD). --- @param #NAVPOINT self --- @param #string Name Name of the fix. Should be unique! --- @param #string Type Type of the point. Default `NAVPOINT.Type.POINT`. --- @param #number Latitude Latitude in DD. --- @param #number Longitude Longitude in DD. --- @return #NAVPOINT self -function NAVPOINT:NewFromLLDD(Name, Type, Latitude, Longitude) - - -- Create a VECTOR from the coordinate. - local Vector=VECTOR:NewFromLLDD(Latitude, Longitude) - - -- Create NAVPOINT. - self=NAVPOINT:NewFromVector(Name, Type, Vector) - - return self -end - - ---- Create a new NAVPOINT class instance relative to a given other NAVPOINT. --- You have to specify the distance and bearing from the new point to the given point. *E.g.*, for a distance of 5 NM and a bearing of 090° (West), the --- new nav point is created 5 NM East of the given nav point. The reason is that this corresponts to convention used in most maps. --- You can, however, use the `Reciprocal` switch to create the new point in the direction you specify. --- @param #NAVFIX self --- @param #string Name Name of the fix. Should be unique! --- @param Navigation.Point#NAVPOINT NavPoint The given/existing navigation point. --- @param #number Distance Distance from the given to the new point in nautical miles. --- @param #number Bearing Bearing [Deg] from the new point to the given one. --- @param #boolean Reciprocal If `true` the reciprocal `Bearing` is taken so it specifies the direction from the given point to the new one. --- @return #NAVFIX self -function NAVPOINT:NewFromNavPoint(Name, NavPoint, Distance, Bearing, Reciprocal) - - if Reciprocal then - Bearing=Bearing-180 + -- Try to get the scenery object. Note not all can be found unfortunately. + if SceneryName then + self.scenery=SCENERY:FindByNameInZone(SceneryName, ZoneName) + if not self.scenery then + self:E(string.format("ERROR: Could not find scenery object %s in zone %s", SceneryName, ZoneName)) + end end - -- Translate. - local Vector=NavPoint.vector:Translate(UTILS.NMToMeters(Distance), Bearing) + -- Alias. + self.alias=string.format("%s %s %s", tostring(ZoneName), tostring(SceneryName), tostring(Type)) - self=NavPoint:NewFromVector(Name, Vector) + -- Set some string id for output to DCS.log file. + self.lid=string.format("NAVAID %s | ", self.alias) + -- Debug info. + self:I(self.lid..string.format("Created NAVAID!")) + return self end @@ -542,158 +548,37 @@ end -- User Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---- Set minimum altitude. --- @param #NAVPOINT self --- @param #number Altitude Min altitude in feet. --- @return #NAVPOINT self -function NAVPOINT:SetAltMin(Altitude) +--- Set frequency the beacon transmits on. +-- @param #NAVAID self +-- @param #number Frequency Frequency in Hz. +-- @return #NAVAID self +function NAVAID:SetFrequency(Frequency) - self.altMin=Altitude + self.frequency=Frequency return self end ---- Set maximum altitude. --- @param #NAVPOINT self --- @param #number Altitude Max altitude in feet. --- @return #NAVPOINT self -function NAVPOINT:SetAltMax(Altitude) +--- Set channel of, *e.g.*, TACAN beacons. +-- @param #NAVAID self +-- @param #number Channel The channel. +-- @param #string Band The band either `"X"` (default) or `"Y"`. +-- @return #NAVAID self +function NAVAID:SetChannel(Channel, Band) - self.altMax=Altitude + self.channel=Channel + self.band=Band or "X" 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 minimum speed. --- @param #NAVPOINT self --- @param #number Speed Min speed in knots. --- @return #NAVPOINT self -function NAVPOINT:SetSpeedMin(Speed) - - self.speedMin=Speed - - return self -end - ---- Set maximum speed. --- @param #NAVPOINT self --- @param #number Speed Max speed in knots. --- @return #NAVPOINT self -function NAVPOINT:SetSpeedMax(Speed) - - self.speedMax=Speed - - return self -end - ---- Set mandatory speed (min speed = max speed). --- @param #NAVPOINT self --- @param #number Altitude Mandatory speed in knots. --- @return #NAVPOINT self -function NAVPOINT:SetSpeedMandatory(Speed) - - self.speedMin=Speed - self.speedMax=Speed - - 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. If min and max altitudes are set, it will return a random altitude between min and max. --- @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 and self.altMin~=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 - - ---- Get the speed. If min and max speeds are set, it will return a random speed between min and max. --- @param #NAVPOINT self --- @return #number Speed in knots. Can be `nil`, if neither min nor max speeds have beeen set. -function NAVPOINT:GetSpeed() - - local speed=nil - if self.speedMin and self.speedMax and self.speedMin~=self.speedMax then - speed=math.random(self.speedMin, self.speedMax) - elseif self.speedMin then - speed=self.speedMin - elseif self.speedMax then - speed=self.speedMax - end - - return speed -end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Private Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---- 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 +-- Add private CLASS functions here. +-- No private NAVAID functions yet. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/Moose Development/Moose/Navigation/Procedure.lua b/Moose Development/Moose/Navigation/Procedure.lua index 2a0cca784..8dd4a4853 100644 --- a/Moose Development/Moose/Navigation/Procedure.lua +++ b/Moose Development/Moose/Navigation/Procedure.lua @@ -94,7 +94,7 @@ APPROACH.Segment={ -- @type APPROACH.Waypoint -- @field #number uid Unique ID of the point. -- @field #string segment The segment this point belongs to. --- @field Navigation.NavFix#NAVFIX navfix The navigation fix that determines the coordinates of this point. +-- @field Navigation.Point#NAVFIX navfix The navigation fix that determines the coordinates of this point. --- APPROACH class version. -- @field #string version @@ -122,6 +122,8 @@ function APPROACH:New(Type, Airbase, Runway) -- Inherit everything from BASE class. self=BASE:Inherit(self, BASE:New()) -- #APPROACH + -- Set approach type. + -- TODO: Check if this is a valid/known approach type. self.apptype=Type if type(Airbase)=="string" then @@ -131,11 +133,14 @@ function APPROACH:New(Type, Airbase, Runway) end if type(Runway)=="string" then - self.airbase:GetRunwayByName(Runway) + self.runway=self.airbase:GetRunwayByName(Runway) else self.runway=Runway end - + + -- Debug info. + self:I("Created new approach for airbase %s: type=%s, runway=%s", self.airbase:GetName(), self.apptype, self.runway.name) + return self end @@ -156,17 +161,17 @@ end --- Add a waypoint to the path of the approach. -- @param #APPROACH self --- @param Navigation.Point#NAVPOINT NavPoint The NAVPOINT. +-- @param Navigation.Point#NAVFIX NavFix The navigation fix. -- @param #string Segment The approach segment this fix belongs to. --- @return #APPROACH self -function APPROACH:AddWaypoint(NavPoint, Segment) +-- @return #APPROACH.Waypoint The waypoint data table. +function APPROACH:AddNavFix(NavFix, Segment) self.wpcounter=self.wpcounter+1 local point={} --#APPROACH.Waypoint point.uid=self.wpcounter point.segment=Segment - point.navfix=NavPoint + point.navfix=NavFix table.insert(self.path, point) @@ -177,6 +182,7 @@ end -- Private Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Add private functions here. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -236,7 +242,7 @@ DEPARTURE.Segment={ -- @type DEPARTURE.Waypoint -- @field #number uid Unique ID of the point. -- @field #string segment The segment this point belongs to. --- @field Navigation.NavFix#NAVFIX navfix The navigation fix that determines the coordinates of this point. +-- @field Navigation.Point#NAVFIX navfix The navigation fix that determines the coordinates of this point. --- DEPARTURE class version. -- @field #string version @@ -296,17 +302,17 @@ end --- Add a waypoint to the path of the DEPARTURE. -- @param #DEPARTURE self --- @param Navigation.Point#NAVPOINT NavPoint The NAVPOINT. +-- @param Navigation.Point#NAVFIX NavFix The navigation fix. -- @param #string Segment The DEPARTURE segment this fix belongs to. --- @return #DEPARTURE self -function DEPARTURE:AddWaypoint(NavPoint, Segment) +-- @return #DEPARTURE.Waypoint The waypoint data. +function DEPARTURE:AddWaypoint(NavFix, Segment) self.wpcounter=self.wpcounter+1 local point={} --#DEPARTURE.Waypoint point.uid=self.wpcounter point.segment=Segment - point.navfix=NavPoint + point.navfix=NavFix table.insert(self.path, point) @@ -317,6 +323,7 @@ end -- Private Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Add DEPARTURE private functions here. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index 789f13f41..e76d15bcf 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -1743,6 +1743,8 @@ function FLIGHTGROUP:OnEventLanding(EventData) if element then self:T3(self.lid..string.format("EVENT: Element %s landed at %s ==> landed", element.name, airbasename)) self:ElementLanded(element, airbase) + else + self:T3(self.lid.."EVENT: Could not get element in landing event") end end @@ -3722,6 +3724,8 @@ function FLIGHTGROUP:_SetFlightPlan(FlightPlan) local wp=self:AddWaypoint(fix.vector, speed, nil, altitude or 10000, false) wp.flightplan=FlightPlan + + wp.name=fix.name end