Hound ELINT is a mission script for DCS. it uses one or more assigned ELINT platforms to approximates location of transmitting enemy radars using triangulation. Platforms are pre-assigned or dynamic assigned assets, they can be Air born, ground units or stationary objects from a set list of assets available.
Hound presents data in serval methods.
System can gather information about Enemy radar deployments and help understand the tactical situation or penetrate enemy defences. Because the System is asset based, you also need to be protecting these assets, as if they are destroyed, you loose your tactical data.
Hound requires MIST and is compatible with MOOSE, Skynet IADS and High-Digit SAMs and more.
Hound system triangulates positions of radars. It does this by taking bearing readings at set times, while recording the platform position. using these plotted data points system can estimate the position. the more points you have, with greater intersection angles between them, there is a better chance of estimating the position correctly. you will never get a perfect "hit" but you may be able to get a position within a 200 meter radius, where you can can use other sensors to pinpoint for a strike, or know where you need to avoid flying.
Only specific units are ELINT capable. In order to get the best positional accuracy you want your best precision platforms positioned as close as possible and as high as possible. Remember the higher you go the longer you can see, simple physics.
placing two C-17s going race-track holding patterns at 30,000 ft can get you positional data on radars more then 200nm away, not the best accuracy of course. using a Comms Tower placed on a high mountain will provide very accurate baseline on which aircraft data can be triangulated. However, tall mountains are not very common, and clear line-of-site is a thing.
Helicopters may be of some use, but they can, using existing mission scripts, transport ground units to tall mountains deep inside enemy territory. Same goes to Fast movers like the Viggen, F-16, JF-17 or the Su-25T. they can dash into enemy territory and help you find the radars trying to hide.
Remember that the system is using a simulated DF to determine the bearing of the radar from the platform. Low precision systems will cause the calculated position to be with a higher ellipse of uncertainty for radar position. below you can find the list of working units and their sensor precision.
Resolution of platforms are derived from antenna size and emitter frequency. shout out to TLTeo for explaining the physics of this.
Hound Currently has a 10 degrees angular resolution cut-off point to avoid introducing "bad data". The the first band that is valid for a platform is denoted in the Minimum Band
column.
Note: While currently not implemented. Intention of including both Viggen and the Su-25T is that they will only be able to participate if they are carrying their ELINT pods
Platform | Accuracy Deg. (C/H Bands) | Min. Band | Remarks |
---|---|---|---|
C-130 | 0.65 / 0.07 | A | |
C-17 | 0.57 / 0.06 | A | Stand-in for RC-135 |
An-30M | 0.92 / 0.10 | A | |
Tu-95 | 0.46 / 0.05 | A | |
Tu-142 | 0.46 / 0.05 | A | |
IL-76MD | 0.60 / 0.06 | A | |
H-6J | 6.54 / 0.70 | C | |
C-47 | 1.91 / 0.20 | A | |
S-3B | 1.59 / 0.17 | A | |
E-2D | 6.54 / 0.70 | C | |
E-3A | 5.09 / 0.55 | C | |
An-26B | 0.98 / 0.10 | A | |
A-50 | 5.09 / 0.55 | C | |
Viggen | 5.09 / 0.55 | C | U22 |
Su-25T | 6.54 / 0.70 | C | Fantasmagoria |
JF-17 | 7.05 / 0.76 | C | KG-600 SPJ |
F-16C | 15.79 / 1.69 | D | Block 50 w/HTS |
* Data with angular resolution below 10 deg is rejected. That is a rudimentary way to drop very bad data.
Platform | Accuracy Deg. (C/H Bands) | Min. Band |
---|---|---|
CH-47D | 1.91 / 0.20 | A |
CH-53E | 2.29 / 0.25 | A |
MIL-26 | 1.15 / 0.12 | A |
UH-60A | 2.86 / 0.31 | B |
SH-60B | 2.86 / 0.31 | B |
Mi-8MT | 2.86 / 0.31 | B |
UH-1H | 5.73 / 0.61 | C |
Ka-27 | 5.73 / 0.61 | C |
Platform | Accuracy Deg. (C/H Bands) | Min. Band |
---|---|---|
SPK-11 | 1.53 / 0.16 | A |
MLRS FDDM | 1.53 / 0.16 | A |
Platform | Accuracy Deg. (C/H Bands) | Min. Band |
---|---|---|
Comms tower M | 0.29 / 0.03 | A |
Platform | Accuracy Deg. (C/H Bands) | Min. Band |
---|---|---|
Anubis C-130J | 0.65 / 0.07 | A |
EF-18G (CJS) | 1.64 / 0.18 | A |
VSN EA-6B Prowler | 2.54 / 0.27 | B |
UH-60L | 2.86 / 0.31 | B |
RC-135W (SSS) | 0.57 / 0.06 | A |
EC-130H (SSS) | 0.65 / 0.07 | A |
P-3C (MAM) | 0.92 / 0.10 | A |
P-8A (CLP) | 0.65 / 0.07 | A |
TU-214R (CLP) | 0.57 / 0.06 | A |
Yes you can. if upgrading from Hound 0.1 please see Breaking changes
Optional scripts - required for TTS (only one of them is required, based on your preference) DCS-gRPC DCS-SimpleTextToSpeech (by ciribob)
For installation of STTS or DCS-gRPC please consult project of choice repo. Both require you to modify "DCS World/Scripts/MissionScripting.lua"
for more information of de-sanitization process, look here.
NOTE the order of scripts - it's important
on a "ONCE" type action with "time more 1" condition, add the scripts in the following order
MIST
DCS-SimpleTextToSpeech
(if TTS via STTS is desired - gRPC is implemented globally)HoundElint.lua
The bare minimum, more customization options are available.
do
Elint_blue = HoundElint:create(coalition.side.BLUE)
Elint_blue:addPlatform("NAME_OF_UNIT_1")
-- it's recommended to have at least two active platform to make system faster and more accurate
Elint_blue:addPlatform("NAME_OF_UNIT_2")
Elint_blue:systemOn()
-- This is a basic setup with map markers only
-- additional stuff (uncomment if desired)
-- Elint_blue:enableAtis() -- ATIS requires STTS, as it is voice only
-- Elint_blue:enableController() -- This will enable Voice+text controller messages
end
It doesn't need to make sense to you, there is actually more explanations ahead. But this is an example of a more complex configuration.
HoundBlue = HoundElint:create(coalition.side.BLUE)
HoundBlue:addPlatform("ELINT North") -- C-130
HoundBlue:addPlatform("ELINT South") -- C-130
HoundBlue:addPlatform("ELINT Galil") -- C-130
HoundBlue:addPlatform("ELINT HERMON") -- Ground Station
HoundBlue:addPlatform("ELINT MERON") -- Ground Station
HoundBlue:addSector("Lebanon")
-- HoundBlue:addSector("North Syria")
-- HoundBlue:addSector("South Syria")
local controller_args = {
freq = "251.000,122.000,35.000",
modulation = "AM,AM,FM",
gender = "male"
}
local atis_args = {
freq = "253.000,124.000",
modulation = "AM,AM"
}
HoundBlue:enableController("Lebanon",controller_args)
HoundBlue:enableAtis("Lebanon",atis_args)
HoundBlue:enableNotifier("default")
HoundBlue:setTransmitter("all","ELINT MERON")
HoundBlue:enableText("all")
HoundBlue:setZone("Lebanon","Sector_Lebanon")
HoundBlue:setMarkerType(HOUND.MARKER.POLYGON)
HoundBlue:enableMarkers()
HoundBlue:enableBDA()
HoundBlue:systemOn()
when this setting is enabled, Hound will print a short status report after each update cycle. (every ~15 seconds by default)
it is controlled by the onScreenDebug
function. this output is disabled by default
-- to enable
HoundBlue:onScreenDebug(true)
-- to disable
HoundBlue:onScreenDebug(false)
First we create hound instance. on creation Hound must have a coalition assigned. this can be done in several ways.
-- direct coalition assignment
HoundInstance = HoundElint:create(coalition.side.BLUE)
An instance without any platforms would be created.
you can also create Hound with an initial platform. coalition will be taken from the Unit assigned. Hound adds units by using their names (or pilot name) not by a group name.
-- create with platform (static object in this case)
HoundInstance = HoundElint:create("Migariya_Elint")
Platforms can be added at any time (before or after system activation)
HoundInstance:addPlatform("ELINT_C17")
and if need be the opposite is also available
HoundInstance:removePlatform("ELINT_C17")
please make sure you go over the available assets list of each to determine what would work best for your mission.
That's it, all you need to do now is to activate the system
HoundInstance:systemOn()
Once activated the system will use all available platforms to locate transmitting radars. Information about these radars is updated periodicity onto the F10 map.
Note: during this first implementation, markers are updated every 2 minutes
You can of course turn it off for any reason with:
HoundInstance:systemOff()
In some cases you would want to always provide accurate positional information on a contact. for example a stationary SAM site you provided strike coordinated for in the Briefing.
you can sync Hound to use the actual unit data as position. The contact will be treated as "Pre-Briefed" and will not update position like the others.
However if a PB concat moves more then 100m from it's original position the special "pre-briefed" flag will be removed and radar will be processed as a normal contact from that point on. you can mark Unit or Group, only valid Hound Radars will be added (it will not add units it will not normally track). if a group was passed and in contains more then one valid radar, all of the radars will be added lua HoundInstance:preBriefedContact('UNIT_NAME') HoundInstance:preBriefedContact('GROUP_NAME')
## Global settings Global settings are best set early, which is why I'm listing them here. However they might effect resources that will only be explained later in this document. So if something looks out of place, don't worry about it.
Hound uses Map markers to indicate the estimated position of the radar tracker. It's a product of the system, and only contains data user can get from the system in other ways (equivalent to making marks on a paper map). Map markers are enabled by default. In addition, if radar went offline, the marker fill will fade slowly over time until it reaches a minimum value on contact timeout (thee time in which all past contact data points are deleted).
However, some mission designers may want to disable the markers.
HoundInstance:disableMarkers()
they can be turned back on with
HoundInstance:enableMarkers()
Hound Supports a few different marker types for the uncertainty ellipse that can be selected. The type of marker is set per Hound instance.
HoundInstance:setMarkerType(HOUND.MARKER.POLYGON)
the available marker types are: | HOUND.MARKER | Description |
---|---|---|
NONE | no ellipse is drawn (only position marker) | |
CIRCLE | a circle of uncertainty will be drawn | |
DIAMOND | a diamond will be drawn with 4 points representing uncertainty ellipse (Default) | |
OCTAGON | ellipse will be drawn with 8 points (diamond with midpoints) | |
POLYGON | ellipse will be drawn as a 16 sides polygon |
Note: More points causes higher CPU usage. DIAMOND is default
Hound does it best to play nice with other Marker generating scripts.
if MOOSE is loaded Hound will default to use UTILS.GetMarkID()
to get the next marker ID.
if that is not available, and MIST is in version 4.5 and above. Hound will attempt to use MIST's mist.marker.getNextId()
method.
if none of those options is available it will use an internal counter to track mark IDs.
if from any reason you still encounter issues you can force Hound to use the internal counter by setting
HOUND.FORCE_MANAGE_MARKERS = true
By default the internal counter starts from 10,000. You can change the initial value to avoid conflicts with other numbering things (which are not MOOSE or MIST) by using the method HOUND.Utils.setInitialMarkId()
. As mentioned earlier, if MOOSE or MIST v4.5 are present their numbering engine will take priority over Hound's internal Numbering.
It is highly recommended that you use one of them (or HOUND.Utils.getMarkId()
) for all other scripted Map markers.
In addition to all that Hound will only delete its own markers (by tracking every Marker ID it's placing)
Position of the platform is a baseline used for the triangulation. In the real world however position on the platform is always never accurate. Older aircraft have INS systems that drift overtime unless updated periodically, while in newer Aircraft a less "drift" system is updated automatically from GPS. To simulate this you can enable position errors. When this setting is enabled, a random error is introduced to platform's position when stored.
HoundInstance:enablePlatformPosErrors()
-- disable (default)
HoundInstance:disablePlatformPosErrors()
By default the Controller and Notifier will push alerts when a radar is destroyed when track is dropped. you may choose to disable this behaviour
HoundInstance:disableBDA()
-- enable (default)
HoundInstance:enableBDA()
-- get current value
local bool = HoundInstance:getBDA()
This setting only affects automatic marking of dead contacts. You can manually mark a contact as dead (and notifications will be transmitted) regardless of BDA settings.
To mark a contact as dead use HoundInstance:markDeadContact(radarUnit)
see extended docs for more information.
By default the Controller will generate the "ELINT" root menu in the base F10 menu. You may choose to change this to a different base location in some cases.
-- target menu MUST be created BEFORE it's assigned to Radio menu
SuperDuperMenu = missionCommands.addSubMenuForCoalition(coalition.side.BLUE,"Fantastic functionality")
-- it is highly recommended to set the new parent menu BEFORE calling enableController (but can be after configureController if called separately).
-- If set after "enableController()" is called, in some cases a user will be required to retake his slot.
HoundInstance:setRadioMenuParent(SuperDuperMenu)
-- after parent has been assigned you can enable controller
HoundInstance:enableController()
Sectors get automatically assigned callsigns. The callsigns are picked from a pool of names. However there is an alternate list, taken from callsigns used by RC-135 squadrons. to use this alternate call sign list by default, you'll need to set the following.
-- enable use of alternate pool
HoundInstance:useNATOCallsignes(true)
-- disable this setting (return to use default pool)
HoundInstance:useNATOCallsignes(false)
The ATIS system has two modes, Normal and NATO low-down.
same report in both will look slightly different.
in the Normal default format, ATIS will also call out radar names and Grid position.
Straight Flush 17, grid GG20, accuracy very high
it is possible to switch it to NATO LOWDOWN format.
6, ACTIVE, BULLSEYE 012 13, accuracy very high
This change is global and preformed via the use of the following:
-- enable Lowdown
HoundInstance:enableNATO()
-- disable lowdown (revert to default)
HoundInstance:disableNATO()
-- get current setting
local bool = HoundInstance:getNATO()
The ATIS system by default will generate a new message every 5 minutes. you can change the update rate if desired.
-- pass desired update interval in seconds
HoundInstance:setAtisUpdateInterval(120)
-- Default setting is
HoundInstance:setAtisUpdateInterval(5*60)
Hound works with multiple timers that will control the frequency of internal tasks. the four timers and their default values are:
scan
controls the interval in which platforms are tested gains radars and data points are added.
process
is the position calculation interval.
menus
is the interval in which the comms menus will be computed.
markers
is the interval in which all map markers will be updated.
you can change the default value if you wish by passing interval name and new value.
this is normally done to tune performance impact.
for example: increasing the scan interval to 20 seconds and the process interval to 60 seconds might help when a very large number of radars are present in the missions and there is suspicion Hound is the cause.
HoundInstance:setTimerInterval("display",180)
The next big building block of Hound are the sectors. Introduced in 0.2 this aims to solve a problem in large servers. in the past there was only one "default" sector that everyone contacted for information. In practice in large missions it was just unmanageable.
A "Sector" is a internal named object that manages communication with players. each sector is assigned a name and a callsign. when initializing Hound a "default" sector is created with the call sign "HOUND". when not passing any sector name argument, "default" sector is the sector that would be affected.
A Sector can be geo fenced, if such geofencing is is set (more on this later) only radars in and around the sector will be reported. see more under Zone management
There are two reserved sector names:
default
- default sector name created with hound instance. it cannot be removed and some features such as geofencing is not available on itall
- all sectors. some settings can be changes across all sectors
using the "all" keyword. this is available on generic config functions not on The most basic command is to add a sector. you will need to provide a name for the sector (not a callsign), this name will be used in the comms menu for example. so you can make it human descriptive or match your SOP .
-- Sector name must be provided
-- here are a few random examples
HoundInstance:addSector("Sukhumi")
HoundInstance:addSector("Abkazia")
HoundInstance:addSector("North Syria")
HoundInstance:addSector("RANGE 13")
You can request a list of all sector names
HoundInstance:listSectors()
or if from some bizarre reason you would like to remove a sector
HoundInstance:removeSector("sectorName")
Sectors have a few options worth knowing.
By default Hound will only broadcast using SRS. You can optionally enable Text messages of all controller messages (ATIS and notifier will remain Voice only). Text notification will only show up for groups that are currently checked in with a controller. enable and disable is per-sector lua HoundInstance:enableText("sectorName") HoundInstance:disableText("anotherSector")
or to all of them using the "all" keyword lua HoundInstance:enableText("all")
#### TTS transmissions Hound is primary built to use Text-To-Speachh messages to communicate. However if from any reason you wish to disable this feature. (which is strictly enabled by default)
you can use the following
HoundInstance:disableTTS("sectorName")
-- to re-enable
HoundInstance:enableTTS("sectorName")
or to all of them using the "all" keyword
HoundInstance:disableTTS("all")
Geofencing a sector will be achieved by assigning a "Zone". There are two valid polygon inputs to the Sector.
it is then added to the sector using the following:
HoundInstance:setZone("sectorName","drawToolPolygon")
-- or
HoundInstance:setZone("sectorName","GroupName")
if both polygon and group share the same name. Polygon will take precedence.
There is also a special case, if "sectorName Sector" is a valid draw polygon you can use it without passing any arguments.
-- This will try and use a polygon called "sectorName Sector" if one exists.
HoundInstance:setZone("sectorName")
You can also get the currently set zone on the sector (nil means not zone is set)
HoundInstance:getZone("sectorName")
To remove a zone from sector use:
HoundInstance:removeZone("sectorName")
A sector can have a transmitter which will broadcast all the TTS messages for the sector. when no transmitter is assigned, everyone on the frequency will be able to hear then transmissions, without any limitations, a "Magic Satlink" if you wish.
Once transmitter is set, SRS will use transmitter's current position for the transmission forcing line-of-sight, maximum radio range and any other SRS limitation that comes with it.
If transmitter unit is destroyed, no TTS transmissions will occur. To resolve it you would either need to set a new transmitter to take over.
you can also remove the transmitter at any time to return to the default "Magic Satlink" state.
Transmitter can be a Unit or a static object, and it's called by Unit/Pilot name
HoundInstance:setTransmitter("sectorName","AWACS_Unit")
Remove transmitter using
HoundInstance:removeTransmitter("sectorName")
you can also use the "all" keyword for apply the transmitter to all sectors
HoundInstance:setTransmitter("all","GCI_bunker")
each sector has a randomly assigned callsign. these callsigns are selected from a pool of callsigns. you can get currently assigned callsign using
local assignedCallsign = HoundInstance:getCallsign("sectorName")
If you wish you can also assign a new callsign
-- choose random callsign from the "generic" pool (default behaviour, not need to use this)
HoundInstance:setCallsign("sectorName")
-- assign the callsign "CALLSIGN" to the sector "sectorName"
HoundInstance:setCallsign("sectorName","CALLSIGN")
there are two callsign pools, one is generic the other is a list of callsigns for RC-135s in the USAF. if you with for a specific sector to use a callsign from the NATO list you can call
HoundInstance:setCallsign("sectorName",true)
-- or
HoundInstance:setCallsign("sectorName","NATO")
if you want ALL sectors to use callsigns from this pool there is a global setting for this. See Global settings -> NATO callsigns
In addition to the map markers described above. Hound is utilizing Text-To-Speech to provide the player with information via SRS. The three communication types are:
they are all configurable as will be described the Text-To-Speach configuration segment below.
The Automated Tactical Information System (ATIS). Will provide an automated information message loop on a set frequency. Default frequency for ATIS is 250.500 AM. This feature can be activated in the default sector with default config using:
HoundInstance:enableAtis()
and turned off with
HoundInstance:disableAtis()
this however is just the very very basic way to configure it and will only affect the "default" sector. The better way to use it would be to enable it on a non-default sector
HoundInstance:enableAtis("Lebanon")
HoundInstance:disableAtis("Lebanon")
However, having all the ATIS in all the sectors broadcast on the same frequency isn't really useful. so you can pass configuration table then enable
HoundInstance:configureAtis("Sukhumi",atis_conf)
HoundInstance:enableAtis("Sukhumi")
or you can pass the configuration on enable
HoundInstance:enableAtis("Sukhumi",atis_conf)
HoundInstance:reportEWR("Sukhumi",true)
-- disable again with
HoundInstance:reportEWR("Sukhumi",false)
-- and set for all of them with HoundInstance:reportEWR("all",true)
* NATO Lowdown format is available as global setting. see [Global Settings -> NATO Lowdown](#nato-lowdown)
* Changing the ATIS update interval is available via global settings. see [Global Settings -> ATIS update interval](#atis-update-interval)
### SAM controller
---
The SAM controller is the main user interface with the system. Via the F10 menu, you can request detailed information about specific tracked radars. the controller defaults to 250.00 AM
basic enable is done via
```lua
HoundInstance:enableController()
as with the ATIS, it's recommended to activate on a non-default sector and pass configuration
HoundInstance:configureController("Saipan",controller_config)
HoundInstance:enableController("Saipan")
or the one liner
HoundInstance:enableController("Saipan",controller_config)
disable is done via
HoundInstance:disableController()
--- or the named sector
HoundInstance:disableController("Saipan")
By default a controller will alert you on new radars detected and on dead emitters. you can disable all controller alerts (does not affect the Notifier).
HoundInstance:disableAlerts("Sukhumi")
-- enable again (default behaviour)
HoundInstance:enableAlerts("Sukhumi")
-- and set for all of them with
HoundInstance:disableAlerts("all")
By default the controller will provide you with MGRS in 10 digits format (5 for easting and 5 northing). this is set by a global variable you can override this to get different precision (i.e 3 will give you 6 digits MGRS)
HOUND.setMgrsPresicion(3)
The controller has a fixed message structure as follows.
This Reads like this:
<Radar Type> <Radar UID>, [Active/Recent/stale etc.] at Bullseye XXX YY, accuracy [Very High/High/Medium/Low etc.],
position <LL in Aircraft format>, I repeat <LL in Aircraft format>,
MGRS <MGRS with HOUND.MGRS_PRECISION>,
elevation XXXX feet MSL,
ellipse is XX by YY, aligned bearing ZZ,
Tracked for XX [minutes/seconds], last seen YY [minutes/seconds] ago.
Advanced users what wish to change this structure may do it.
If you are satisfied by only suppressing the Extended uncertainty and the Extended Tracking time info you can do so by invoking HOUND.showExtendedInfo()
function. This will have an affect globally.
HOUND.showExtendedInfo(false)
If
a more extensive change is desired, The recommended way to achieve it is to COPY
the HOUND.Contact:generateTtsReport
and HOUND.Contact:generateTextReport
functions from src/301 - HoundContact_comms.lua
file in this repo to a new file. In that new file perform the changes you want. To activate load the new file to the mission using Do script file
AFTER the main Hound script is loaded. this will replace the original implementation without editing the original file. allowing a simpler upgrades to newer Hound versions without loosing you changes.
This, as the name suggests is notification only agent. it functions independently of controller or ATIS and will only report pop-up and if enable radar destruction alerts. this is intended to be operated on a different frequency then the controller (which has the same alerting capacity). This may be used for improving SA on Air-To-Air frequency or on general strike channels.
Notifier has a special case when used under "default" sector when radar is inside a geo-fenced sector. In this scenario it will report using sector name rather then with location. for example:
Attention All Aircraft! This is HOUND. New threat detected! Straight flush 11 is now Alive, bullseye XXX YY, Grid ZZ 1 4.
Special case: Attention All Aircraft! this is HOUND. New thread detected! Straight flush 11 is now Alive in Bander Abbas.
by default it will broadcast on 243.000AM and 121.500AM, i.e Guard frequency. but will accept TTS configuration.
Example snippets:
-- enable on default sector with default settings
HoundInstance:enableNotifier()
-- enable with custom config on separate sector
HoundInstace:enableNotifier("Bander Abbas",notifier_config)
-- configure and set frequency inline without enabling
HoundInstace:enableNotifier("Qeshem",{freq=254,modulation="AM",gender="male"})
Oviously, you may want to tweak the radio to better work with you mission. this can be done using an arguments table and passing it to the configuration function.
possible settings are slightly different based on your TTS provider of choice.
by default, if correct gRPC version is present, Hound will use it over STTS to change it and use STTS regardless. you need to set a global variable (which is true by default)
HOUND.PREFER_GRPC_TTS = false
args = {
freq = 250.000,
modulation = "AM", -- optional
volume = "1.0", -- optional
speed = <speed> -- number default is 0/1 for controller/atis. range is -10 to +10 on windows TTS. for google it's 0.25 to 4.0
gender = "male"|"female",
culture = "en-US"|"en-UK" -- (any installed on your system)
isGoogle = true/false -- use google TTS (requires additional STTS config)
}
args = {
freq = 250.000,
speed = <speed> -- optional, range is -10 to +10 on windows TTS. you can also specify a number between 50 and 250 which will be treated as speech speed (100% is normal)
volume = "1.0", -- optional
gender = "male"|"female", -- optional
culture = "en-US"|"en-UK" -- (must be available on you system)
name = "name_of_voice", -- optional (overrides gender/culture settings)
provider = {} -- optional gRPC.tts provider settings (consult DCS-gRPC). for example ATIS works with windows TTS. controller via a cloud provider (like AWS or Azure)
#### applying the settings
you can override one or more, and you can also have multiple frequencies.
you then pass the table into the appropriate functions
```lua
HoundInstance:configureController(args)
HoundInstance:configureAtis(args)
for example:
controller_args = {
freq = "251,35"
modulation = "AM,FM"
}
atis_args = {
freq = 251.500,
}
HoundInstance:configureController(controller_args)
HoundInstance:configureAtis(atis_args)
HoundInstance:enableController()
HoundInstance:enableAtis()
This will change ATIS frequency to 251.5 and enable ATIS and will enable Controller both in Text and in Voice, while transmitting on two frequencies 251.0 AM and 35 FM
Introduced with Hound 0.2 you now have Hound event handling. This for example allows you to preform scripted actions on specific events. available events are (Note that reserved events are not yet emitted): | name | id |
---|---|---|
HOUND_ENABLED | 1 | |
HOUND_DISABLED | 2 | |
PLATFORM_ADDED | 3 | |
PLATFORM_REMOVED | 4 | |
PLATFORM_DESTROYED | 5 | |
TRANSMITTER_ADDED | 6 | |
TRANSMITTER_REMOVED | 7 | |
TRANSMITTER_DESTROYED | 8 | |
RADAR_NEW | 9 | |
RADAR_DETECTED | 10 | |
RADAR_UPDATED | 11 | |
RADAR_DESTROYED | 12 | |
RADAR_ALIVE | 13 | |
RADAR_ASLEEP | 14 | |
SITE_NEW | 15 (RESERVED) | |
SITE_CREATED | 16 (RESERVED) | |
SITE_UPDATED | 17 (RESERVED) | |
SITE_REMOVED | 18 (RESERVED) | |
SITE_ALIVE | 19 (RESERVED) | |
SITE_ASLEEP | 20 (RESERVED) |
Event structure is as follows
houndEvent = {
id = <HOUND.EVENT> enum,
coalition = <coalition.side> enum of coalition emitting the event,
houndId = Hound Instance ID that emitted the event,
initiator = DCS unit or HoundContact
time = time of the event (timer.getTimer())
}
to use them you need to create a table with the function onHoundEvent(event)
and register it.
FakeEventHandler = {}
function FakeEventHandler:onHoundEvent(event)
if event.coalition == coalition.side.BLUE then
if event.id == HOUND.EVENTS.RADAR_DETECTED then
local contact = event.initiator
trigger.action.outTextForCoalition(event.coalition,"Let's pretend a SEAD flight was fragged to strike " .. contact:getName())
end
if event.id == HOUND.EVENTS.PLATFROM_DESTROYED then
trigger.action.outTextForCoalition(event.coalition,initiator:getName() .. "has been destroyed")
end
end
end
HOUND.addEventHandler(FakeEventHandler)
to remove use
HOUND.removeEventHandler(CustomHoundScript)
NOTE: Event handlers are global so make sure you validate coalition or houndId as the event might be from a different Instance from a different coalition
RADAR_DESTROYED event is delayed from the DCS Unit destroyed event, so unit is gone by then. unit field in a dead contact is unit-name not unit object like on other events. Try and use initiator.DCSgroupName whenever possible
when running a large mission with a huge Air defence network it is not uncommon to encounter some performance issues.
These issues are caused by the huge number of markers needed to be created and DCS' ability to manage them.
Here are some tips to help you mitigate this.
HoundInstance:disableMarkers()
HoundInstance:setMarkerType(HOUND.MARKER.NONE)
HoundInstance:setTimerInterval("display",180)
Current implementation supports two types of export. LUA and CSV.
HoudnInstace:getContacts()
Calling this function will return a LUA table
{
ewr = {
count = 0,
contacts = {}
},
sam = {
count = 0,
contacts = {}
}
}
Each contact will be added to the appropriate category and count will be updated to match number of contacts in each category. data structure of each record will follow this pattern.
{
typeName = <String ("straight flush","P-19")>
uid = <int (2 digits)>
DCSunitName = <String (Name of actual DCS Unit)>
maxWeaponsRange = <Int (Max range of group weapons in Meters)>
last_seen = <float (time last spotted by platform in seconds, timer.getAbsTime)>
detected_by = <table (list of platform names that detected contact)>
if contact has position then
pos = <table (DCS point of estimated position)>
LL = {
lat = <Float>,
lon = <Float>
}
accuracy = <String>
uncertenty = {
major = <Int (meters)>,
minor = <Int (meters)>,
heading = <Float (deg)>
}
end
}
HoundInstance:dumpIntelBrief()
this will crate a file in the DCS saved games folder. default filename is "hound_contacts_XX.csv" (where 'XX' is the Hound instance UID) you can specify a filename if desired:
HoundInstance:dumpIntelBrief("custom_name.csv")
CSV structure:
TrackId,NatoDesignation,RadarType,State,Bullseye,Latitude,Longitude,MGRS,Accuracy,lastSeen,DCStype,DCSunit,DCSgroup,ReportGenerated
Sample data
TrackId,NatoDesignation,RadarType,State,Bullseye,Latitude,Longitude,MGRS,Accuracy,lastSeen,DCStype,DCSunit,DCSgroup,ReportGenerated
I-1,2,Fan-song,Down,187/78,33.721733,35.800634,36S YC 5951 3482,Precise,1700,SNR_75V,SYR_SA-2_TR,SYR_SA-2,1705
I-2,2 or 3,Flat Face,Active,187/78,33.723213,35.799935,36S YC 5944 3498,Precise,1705,p-19 s-125 sr,SYR_SA-2_SR,SYR_SA-2,1705
E-12,11 or 17,Snow Drift,Active,186/77,33.734985,35.821898,36S YC 6144 3634,High,1705,SA-11 Buk SR 9S18M1,SYRIA gnd 3 unit1,SYRIA gnd 3,1705
E-10,6,Straight Flush,Active,189/84,33.622484,35.727605,36S
YC 5303 2363,High,1705,Kub 1S91 str,SYRIA gnd 2 unit1,SYRIA gnd 2,1705
E-11,6,Straight Flush,Active,181/71,33.845855,35.952393,36S YC 7318 4898,Very High,1705,Kub 1S91 str,SYRIA gnd 1 unit1,SYRIA gnd 1,1705
E-9,EWR,Box Spring,Active,185/96,33.418094,35.864466,36S YC 6636 130,Very Low,1705,1L13 EWR,EWR-SKYNET-1,EWR-SKYNET-0,1705
I-3,EWR,Box Spring,Active,147/60,34.207544,36.618624,37S BT 8059 8773,Precise,1705,1L13 EWR,EWR-SKYNET-4-1,EWR-SKYNET-4,1705
I-4,EWR,Box Spring,Active,191/81,33.678493,35.704000,36S YC 5068 2979,Precise,1705,1L13 EWR,EWR-SKYNET-1-1,EWR-SKYNET-1,1705
I-5,EWR,Box Spring,Active,170/44,34.301650,36.114852,37S BT 3446 9937,Precise,1705,1L13 EWR,EWR-SKYNET-5-1,EWR-SKYNET-5,1705
I-6,EWR,Box Spring,Active,200/75,33.820852,35.486437,36S YC 3012 4507,Precise,1705,1L13 EWR,EWR-SKYNET-6-1,EWR-SKYNET-6,1705
I-7,EWR,Box Spring,Active,185/64,33.950048,35.878007,36S YC 6597 6034,Precise,1705,1L13 EWR,EWR-SKYNET-2-1,EWR-SKYNET-2,1705
I-8,EWR,Box Spring,Active,183/52,34.151685,35.911686,36S YC 6845 8280,Precise,1705,1L13 EWR,EWR-SKYNET-3-1,EWR-SKYNET-3,17050
NOTE: This function requires you do de-sanitize io
and lfs
modules in DCS scripting engine.
If you are upgrading from 0.1 please note that some changes will be required.
enableController()
no longer accepts boolean to enable or disable text. please use enableText()
call.ATIS
in it needs to be changed to have Atis
- note the capitalization.setTransmitter()
is now a sector function. in general passing everything directly to Instance.controller
or Instance.atis
will no longer work due to changes in the internal architecture.
From 0.2 to 0.3 there was an internal change and all classes (except form HoundElint
) where wrapped into HOUND
class (rather then several independent classes).
By default the DCS scripting engine blocks all access to the OS to avoid potential security risks. some functions, most notably anything that needs to write to disk, will not work in this default state. You'll need to "De-sanitize" the DCS Scripting Engine and allow these LUA core modules to be used.
NOTE: This is DCS core files changes, that grants DCS access to functions that allows it to run potential malicious code. USE WITH CAUTION
This is done by editing a single core DCS lua file. this change will be reverted on every DCS update and will need to be re-applied.
open the file <DCS_ROOT_FOLDER>/scripts/MissionScripting.lua
in your favourite text editor (Notepad++ for example)
in that file you'll see the following 3 lines.
sanitizeModule('os')
sanitizeModule('io')
sanitizeModule('lfs')
Each of these lines represent a core lua module that is disabled by DCS Scripting Engine. to enable them just comment out the line that corresponds to the module needed. when all 3 are enabled, that part of the file will look like this
-- sanitizeModule('os')
-- sanitizeModule('io')
-- sanitizeModule('lfs')
for example, STTS require all 3 to be available.
dumpIntelBrief requires io
and lfs
to be available
And a very special thanks is (and will always be) reserved to those who choose to click the button below :)