From 0a9717a8c2a6d884a6c9730e5d5083310e6b3184 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 13 Apr 2025 23:14:19 +0200 Subject: [PATCH] RADIOS - Added new class RADIOS --- Moose Development/Moose/Modules.lua | 1 + Moose Development/Moose/Modules_local.lua | 1 + Moose Development/Moose/Navigation/Radios.lua | 324 ++++++++++++++++++ Moose Development/Moose/Utilities/Enums.lua | 25 ++ 4 files changed, 351 insertions(+) create mode 100644 Moose Development/Moose/Navigation/Radios.lua diff --git a/Moose Development/Moose/Modules.lua b/Moose Development/Moose/Modules.lua index fecf7f271..24c23898a 100644 --- a/Moose Development/Moose/Modules.lua +++ b/Moose Development/Moose/Modules.lua @@ -189,5 +189,6 @@ __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Tasking/Task_Capture_Dispatch __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Navigation/Point.lua' ) __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Navigation/Beacons.lua' ) +__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Navigation/Radios.lua' ) __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Globals.lua' ) diff --git a/Moose Development/Moose/Modules_local.lua b/Moose Development/Moose/Modules_local.lua index 15e1b3b05..0fea70e2e 100644 --- a/Moose Development/Moose/Modules_local.lua +++ b/Moose Development/Moose/Modules_local.lua @@ -181,5 +181,6 @@ __Moose.Include( 'Tasking\\Task_Capture_Dispatcher.lua' ) __Moose.Include( 'Navigation\\Point.lua' ) __Moose.Include( 'Navigation\\Beacons.lua' ) +__Moose.Include( 'Navigation\\Radios.lua' ) __Moose.Include( 'Globals.lua' ) diff --git a/Moose Development/Moose/Navigation/Radios.lua b/Moose Development/Moose/Navigation/Radios.lua new file mode 100644 index 000000000..5b1d5e013 --- /dev/null +++ b/Moose Development/Moose/Navigation/Radios.lua @@ -0,0 +1,324 @@ +--- **NAVIGATION** - Airbase radios. +-- +-- **Main Features:** +-- +-- * Get radio frequencies of airbases +-- +-- === +-- +-- ## Example Missions: +-- +-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/Navigation%20-%20Radios). +-- +-- === +-- +-- ### Author: **funkyfranky** +-- +-- === +-- @module Navigation.Radios +-- @image NAVIGATION_Radios.png + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +--- RADIOS class. +-- @type RADIOS +-- +-- @field #string ClassName Name of the class. +-- @field #number verbose Verbosity of output. +-- @field #table radios Radios. +-- +-- @extends Core.Base#BASE + +--- *It's not true I had nothing on, I had the radio on.* -- *Marilyn Monroe* +-- +-- === +-- +-- # The RADIOS Concept +-- +-- This class is desinged to make information about radios of a map/theatre easier accessible. The information contains mostly the frequencies of airbases of the map. +-- +-- **Note** that try to avoid hard coding stuff in Moose since DCS is updated frequently and things change. Therefore, the main source of information is either a file `radio.lua` that can be +-- found in the installation directory of DCS for each map or a table that the user needs to provide. +-- +-- # Basic Setup +-- +-- A new `RADIOS` object can be created with the @{#RADIOS.NewFromFile}(*radio_lua_file*) function. +-- +-- local radios=RADIOS:NewFromFile("\Mods\terrains\\radios.lua") +-- radios:MarkerShow() +-- +-- This will load the radios from the `` for the specific map and place markers on the F10 map. This is the first step you should do to ensure that the file +-- you provided is correct and all relevant radios are present. +-- +-- # User Functions +-- +-- ## F10 Map Markers +-- +-- ## Position +-- +-- ## Closest Radio +-- +-- +-- @field #RADIOS +RADIOS = { + ClassName = "RADIOS", + verbose = 0, + radios = {}, +} + +--- Radio item data structure. +-- @type RADIOS.Radio +-- @field #string radioId Radio ID. +-- @field #table role Roles of the radio (usually {"ground", "tower", "approach"}). +-- @field #table callsign Callsigns of the radio (usually the airbase name). +-- @field #table frequency Frequencies of the radios. +-- @field #table position Position table. +-- @field #table sceneObjects Scenery objects. +-- @field #string name Name of the airbase. +-- @field Wrapper.Airbase#AIRBASE airbase Airbase. + +--- Radio item data structure. +-- @type RADIOS.Frequency +-- @field #number modu Modulation type. +-- @field #number freq Frequency in Hz. + + +--- RADIOS class version. +-- @field #string version +RADIOS.version="0.0.0" + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- ToDo list +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +-- TODO: A lot... + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Constructor(s) +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +--- Create a new RADIOS class instance from a given table. +-- @param #RADIOS self +-- @param #table RadioTable Table with radios info. +-- @return #RADIOS self +function RADIOS:NewFromTable(RadioTable) + + -- Inherit everything from BASE class. + self=BASE:Inherit(self, BASE:New()) -- #RADIOS + + local airbasenames=AIRBASE.GetAllAirbaseNames() + + for _,_radio in pairs(RadioTable) do + local radio=_radio --#RADIOS.Radio + + --UTILS.PrintTableToLog(radio) + --UTILS.PrintTableToLog(radio.callsign) + + -- The table structure of callsign is a bit awkward. We need to get the airbase name. + local cs=radio.callsign[1] + if cs and cs.common then + radio.name=cs.common[1] + elseif cs and cs.nato then + radio.name=cs.nato[1] + else + radio.name="Unknown" + end + + --UTILS.PrintTableToLog(radio.callsign) + + radio.name=self:_GetAirbaseName(airbasenames, radio.name) + + radio.airbase=AIRBASE:FindByName(radio.name) + + if radio.airbase then + radio.coordinate=radio.airbase:GetCoordinate() + end + + -- Add to table + table.insert(self.radios, radio) + end + + -- Debug output + self:I(string.format("Added %d radios", #self.radios)) + + return self +end + + +--- Create a new RADIOS class instance from a given file. +-- @param #RADIOS self +-- @param #string FileName Full path to the file containing the map radios. +-- @return #RADIOS self +function RADIOS:NewFromFile(FileName) + + -- Inherit everything from BASE class. + self=BASE:Inherit(self, BASE:New()) -- #RADIOS + + local exists=UTILS.FileExists(FileName) + + if exists==false then + self:E(string.format("ERROR: file with radios info does not exist! File=%s", tostring(FileName))) + return nil + end + + -- This will create a global table `radio` + dofile(FileName) + + -- Get radios from table. + self=self:NewFromTable(radio) + + return self +end + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- User Functions +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +--- Get 3D position vector of a specific radio. +-- @param #RADIOS self +-- @param #RADIOS.Radio radio The radio data structure. +-- @return DCS#Vec3 Position vector. +function RADIOS:GetVec3(radio) + return radio.vec3 +end + +--- Get COORDINATE of a specific radio. +-- @param #RADIOS self +-- @param #RADIOS.Radio radio The radio data structure. +-- @return Core.Point#COORDINATE The coordinate. +function RADIOS:GetCoordinate(radio) + return radio.coordinate +end + +--- Add markers for all radios on the F10 map. +-- @param #RADIOS self +-- @param #RADIOS.Radio Radio (Optional) Only this specifc radio. +-- @return #RADIOS self +function RADIOS:MarkerShow(Radio) + + for _,_radio in pairs(self.radios) do + local radio=_radio --#RADIOS.Radio + if Radio==nil or Radio.radioId==radio.radioId then + local coord=self:GetCoordinate(radio) + if coord then + local text=self:_GetMarkerText(radio) + if radio.markerID then + UTILS.RemoveMark(radio.markerID) + end + radio.markerID=coord:MarkToAll(text) + end + end + end + + return self +end + +--- Remove markers of all radios from the F10 map. +-- @param #RADIOS self +-- @param #RADIOS.Radio Radio (Optional) Only this specifc radio. +-- @return #RADIOS self +function RADIOS:MarkerRemove(Radio) + + for _,_radio in pairs(self.radios) do + local radio=_radio --#RADIOS.Radio + if Radio==nil or Radio.radioId==radio.radioId then + if radio.markerID then + UTILS.RemoveMark(radio.markerID) + radio.markerID=nil + end + end + end + + return self +end + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Private Functions +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +--- Get text displayed in the F10 marker. +-- @param #RADIOS self +-- @param #RADIOS.Radio radio The radio data structure. +-- @return #string Marker text. +function RADIOS:_GetMarkerText(radio) + + local text=string.format("Radio %s", tostring(radio.name)) + for b,f in pairs(radio.frequency) do + local frequency=f --#RADIOS.Frequency + local mod=frequency[1] + local fre=frequency[2] + local freq, funit=self:_GetFrequency(fre) + --UTILS.PrintTableToLog(frequency) + local band=self:_GetBandName(b) + text=text..string.format("\n%s: %.3f %s", band, freq, funit) + end + + return text +end + + +--- Get converted frequency. +-- @param #RADIOS self +-- @param #number freq Frequency in Hz. +-- @return #number Frequency in better unit. +-- @return #string Unit ("Hz", "kHz", "MHz"). +function RADIOS:_GetFrequency(freq) + + freq=freq or 0 + local unit="Hz" + + if freq>=1e6 then + freq=freq/1e6 + unit="MHz" + elseif freq>=1e3 then + freq=freq/1e3 + unit="kHz" + end + + return freq, unit +end + +--- Get name of frequency band. +-- @param #RADIOS self +-- @param #number BandNumber Band as number. +-- @return #string Band name. +function RADIOS:_GetBandName(BandNumber) + + if BandNumber~=nil then + for bandName,bandNumber in pairs(ENUMS.FrequencyBand) do + if bandNumber==BandNumber then + return bandName + end + end + end + + return "Unknown" +end + +--- Get name of frequency band. +-- @param #RADIOS self +-- @param #table airbasenames Names of all airbases. +-- @param #string name Name of airbase. +-- @return #string Name of airbase +function RADIOS:_GetAirbaseName(airbasenames, name) + + local airbase=AIRBASE:FindByName(name) + + if airbase then + return name + else + for _,airbasename in pairs(airbasenames) do + if string.find(airbasename, name) then + return airbasename + end + end + end + + return "Unknown" +end + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/Moose Development/Moose/Utilities/Enums.lua b/Moose Development/Moose/Utilities/Enums.lua index a269fb972..4e6ef999f 100644 --- a/Moose Development/Moose/Utilities/Enums.lua +++ b/Moose Development/Moose/Utilities/Enums.lua @@ -1359,3 +1359,28 @@ ENUMS.FARPObjectTypeNamesAndShape ={ [ENUMS.FARPType.PADSINGLE] = { TypeName="FARP_SINGLE_01", ShapeName="FARP_SINGLE_01"}, } +--- Radio frequency bands (HF, VHF, UHF) +-- @type ENUMS.FrequencyBand +-- @field #number HF High frequency +-- @field #number VHF_LOW Very high frequency +-- @field #number VHF_HI Very high frequency +-- @field #number UHF Ultra high frequency +ENUMS.FrequencyBand = { + HF = 0, + VHF_LOW = 1, + VHF_HI = 2, + UHF = 3, +} + +--- Radio modulation types (AM, FM) +-- @type ENUMS.ModulationType +-- @field #number AM Amplitude modulation +-- @field #number FM Frequency modulation +-- @field #number AMFM Amplitude and frequency modulation +-- @field #number DISCARD Discard modulation +ENUMS.ModulationType = { + AM = 0, + FM = 1, + AMFM = 2, + DISCARD = -1, +}