Skip to content

Commit

Permalink
Release v0.10.0
Browse files Browse the repository at this point in the history
* fix IntegerBuffer code snippet
* IntegerBuffer snippet is now prioritized over the ServoOutput snippet
* document Potentiometer code snippet and expose the parameters for the EWMA filter
* remove "Installed Modules" list (now that module definitions are being installed as plugins, this list will most likely be identical to the list of all module definitions anyway)
* add "Hub Scripts" feature (the DCS-BIOS Hub can now run Lua scripts that can remap commands and outputs depending on the active aircraft)
  • Loading branch information
jboecker committed Nov 12, 2019
2 parents eee7a5c + 5ef9960 commit 21e288c
Show file tree
Hide file tree
Showing 26 changed files with 1,497 additions and 258 deletions.
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: v0.9.3+{build}
version: v0.10.0+{build}
pull_requests:
do_not_increment_build_number: true
branches:
Expand Down
18 changes: 18 additions & 0 deletions doc/code-snippets.rst
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,24 @@ it sends "-" or "+" followed by a number. This number must be between 0 and 6553
Most code examples set this number to 3200 by default, but you can change it to suit your needs.
For a course dial (such as found on an HSI), setting this to 182 (65536/360) will likely advance the virtual cockpit dial by one degree for each detent.

Potentiometer
-------------

The Potentiometer code snippet will read the position of a potentiometer connected to an analog input pin::

DcsBios::PotentiometerEWMA<5, 128, 5> stallVol("STALL_VOL", A0);

Connect one outer pin of the potentiometer to the supply voltage, the other outer pin to ground, and the middle pin ("slider") to an analog input pin on your Arduino board.

The numbers in the angle brackets are the poll interval in milliseconds (default 5), the hysteresis (default 128) and the divisor (default 5) for an `exponentially weighted moving average filter <https://en.wikipedia.org/wiki/Moving_average>`_.
The default values should be OK for most cases. If the potentiometer is so noisy that it constantly sends new values, try increasing the hysteresis or increasing the divisor.
If the potentiometer in the virtual cockpit takes too long to catch up to the real one, you can try decreasing the divisor or decreasing the poll interval.

.. note::

The hysteresis is applied after scaling the value read from the Arduino's analog input to a range of 0 to 65535. Because the resolution of the Arduino board's analog-to-digital converter is 10 bit (0 to 1024),
the hysteresis value should be a multiple of 64 (modifications in smaller increments do not make much sense). The default of 128 is equal to two counts of the ADC.

ActionButton
------------

Expand Down
8 changes: 6 additions & 2 deletions doc/control-reference.rst
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
The Control Reference
=====================

A big part of DCS-BIOS are "module definitions" which tell DCS-BIOS which input and output elements exist in an aircraft, how to determine their current state, and how to operate them in the virtual cockpit using Lua scripts in DCS: World.
"Module definitions" tell DCS-BIOS which input and output elements exist in an aircraft, how to determine their current state, and how to operate them in the virtual cockpit using Lua scripts in DCS: World.
The Control Reference lets you look at everything that is defined in a module definition.

In other words, it shows you every dial, toggle switch, push button, indicator light and display that DCS-BIOS knows about.

.. note::

Module definitions are installed using the plugin manager (see :doc:`installation`). The exception are the built-in "MetadataStart" and "MetadataEnd" modules, which provide the name of the currently active aircraft and a counter that is increased after every frame.


On the first screen, you can select a module definition, which usually corresponds with an aircraft model.

Once you click on a module definition, you can either select a category of "controls" to browse, or search for a specific control by name or description using the search field.
Expand Down
20 changes: 11 additions & 9 deletions doc/dashboard.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,7 @@ The other two indicators show the current state of two settings that you can tog
* When **Enable Lua Console** is checked and the Lua Console has been set up on the :doc:`DCS Connection<dcs-connection>` screen, you can use the web interface to execute arbitrary snippets of Lua code within DCS.

.. warning::
Note that if both of these settings are enabled at the same time, anyone who can access TCP port 5010 on your computer can run arbitrary code on your machine. If you do this, make sure your computer is not directly reachable via the internet.


Installed Modules
-----------------

Below the status indicators, you will find shortcuts to the :doc:`control reference documentation <control-reference>` for any installed DCS: World modules that are supported by DCS-BIOS.

.. note:: DCS-BIOS counts a module it knows about as "installed" if it can find a folder of the same name under `mods/aircraft` in either the release or open beta version of DCS: World. This does not work when the folder name differs from the name of the DCS-BIOS module definition, e.g. for the F-18.
Note that if the Lua Console is enabled, anyone who can access TCP port 5010 on your computer can run arbitrary code on your machine. If you enable "access over the network" as well, this includes anyone who can directly connect to your computer over the network. If you do this, make sure your computer is not directly reachable from the public internet.

Managing Serial Port Connections
--------------------------------
Expand All @@ -50,3 +42,13 @@ The "Disconnect All" button disconnects from all COM ports.

The "Connect All Auto" button connects to all COM ports that have autoconnect enabled.

Managing Hub Scripts
--------------------

At the end of the Dashboard, you can manage a list of "hub scripts". Hub scripts can be used to remap commands and exported data, so you can use a simpit you built for one specific airframe with other DCS: World modules.
Learn more in the :doc:`hub-scripts` section.

* Add a hub script by clicking the "Add" button and entering the full path to the script file. You can copy the full path of a file to your clipboard by holding the Shift key while right-clicking it in Windows Explorer and then selecting "Copy as path" from the context menu.
* To remove a hub script from the list, click the "x" button next to it.
* Enable or disable a hub script with the checkbox in front of it. Disabled scripts remain in the list but are not loaded.
* Reload all hub scripts by clicking the "Reload Scripts" button above the list. Note that scripts are not automatically reloaded when you enable, disable, add or remove a list item; you have to click the "Reload Scripts" button for changes to take effect.
2 changes: 1 addition & 1 deletion doc/hardware.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ With DCS-BIOS, you can build your own control panels and connect them to DCS: Wo
Choosing an Arduino board
-------------------------

Arduino board are small PCBs built around a microcontroller, which you can program with the Arduino IDE (Integrated Development Environment). You can learn more about the Arduino project at `<https://www.arduino.cc>`_.
Arduino boards are small PCBs built around a microcontroller, which you can program with the Arduino IDE (Integrated Development Environment). You can learn more about the Arduino project at `<https://www.arduino.cc>`_.

There are many different Arduino boards available. DCS-BIOS supports boards that feature the ATMega328 or the ATMega2560 microcontrollers. That includes the Arduino Uno, Nano, Pro Mini and Mega 2560 boards.

Expand Down
155 changes: 155 additions & 0 deletions doc/hub-scripts.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
Hub Scripts
===========

.. note::

Hub Scripts are a new feature. Although it has been tested in a practical use case for about a week,
the API that is available to the scripts might still be changed if serious bugs or performance issues
are discovered with the current implementation.

Hub scripts are scripts written in the `Lua programming language <https://www.lua.org/manual/5.1/>`_ that are executed by the DCS-BIOS Hub.
A hub script can read data that is coming from DCS ("sim data") and override data that is sent to the serial ports ("panel data").
It can also intercept commands being sent to the DCS-BIOS Hub and send commands to DCS.

Hub scripts are mostly used to make a physical cockpit that was built for a specific airframe work with other DCS: World modules.

Lifecycle
---------

On the :doc:`Dashboard <dashboard>` screen, you can configure a list of hub scripts. These scripts are executed when the DCS-BIOS Hub starts.
When the "Reload Scripts" button is clicked, the Lua state is thrown away, a new Lua state is created and all hub scripts are executed again
(that means no data survives a click of the "Reload Scripts" button).

Lua Environment
---------------

The DCS-BIOS Hub is using `gopher-lua <https://github.com/yuin/gopher-lua>`_, an implementation of Lua 5.1 in the Go programming language.
Lua 5.1 is the same version that DCS: World uses for its Lua scripts. However, as it is written in Go, you won't be able to load Lua libraries written in C++.
See also: `Differences between Lua and GopherLua <https://github.com/yuin/gopher-lua#differences-between-lua-and-gopherlua>`_

.. highlight:: lua

All hub scripts are executed within the same Lua state, but each hub script is loaded in its own global environment.
That means you can use global variables in your hub script without worrying about conflicts with other hub scripts.

For debugging, you can use the :doc:`Lua Console <lua-console>` and select the "hub" environment. To execute code in the global environment of
a specific hub script, use the *enterEnv* function like this::

enterEnv("myscript.lua") -- myscript.lua must be a suffix of the script path
-- any code after the enterEnv line will be executed in the global Lua environment
-- of the first hub script whose path ends with "myscript.lua" (case insensitive match).

return MyGlobalVariable -- inspect the value of MyGlobalVariable

The DCS-BIOS Hub provides a few useful functions in the "hub" Lua module, which is provided automatically in the global variable "hub".
The following sections will describe these functions.

Registering Callbacks
---------------------

An **output callback** is a function that takes no output parameters and will be called whenever new data from DCS has been received.
Use *hub.registerOutputCallback()* to create an output callback:

.. code::
hub.registerOutputCallback(function()
-- use hub.getSimString() and hub.getSimInteger() here
-- to access data from the sim
end)
An **input callback** is a function receiving two arguments (*cmd* and *arg*) and returning a boolean.
It is called whenever a command is received via a serial port.

If the callback function returns *true*, the command is not forwarded to DCS.

An input callback will typically remap commands by using *hub.sendSimCommand()* to send a different command and then returning true to prevent
the original command from being sent to DCS::

-- remap the "UFC_B1" command from a Harrier cockpit to "UFC_1" in the Hornet:
hub.registerInputCallback(function(cmd, arg)
local acftName = hub.getSimString("MetadataStart/_ACFT_NAME")
if acftName == "FA-18C_hornet" then
if cmd == "UFC_B1" then
hub.sendSimCommand("UFC_1", arg)
return true
end
end
end)


.. note::

Output callbacks are executed in the order they were registered. An output callback that has been registered later can overwrite panel data that was set by callbacks that were registered earlier.

Input callbacks are executed in the *reverse* order they were registered. If one input callback returns true, the remaining ones will not be called.
An input callback that has been registered later can intercept a command before callbacks that were registered earlier get the chance.

This means that when multiple hub scripts want to set the same output value or intercept the same command, the script that is last in the list always wins.

Sending Commands to DCS: World
------------------------------

You can send a command to DCS: World using the *hub.sendSimCommand* function.
For example, to click the master caution button in the A-10C::

hub.sendSimCommand("UFC_MASTER_CAUTION", "1")
hub.sendSimCommand("UFC_MASTER_CAUTION", "0")

The channel for commands to DCS has a buffer size of 10, so you can send small sequences like pushing and releasing a button
without worrying about blocking anything.

Reading Data from DCS: World
----------------------------

You can access the most recent data that was received from DCS: World with the *getSimString* and *getSimInteger* functions.
They take a control identifier of the form *AircraftName/ElementName* and return a string or integer value. If the control identifier is invalid,
*getSimInteger* will return -1 and *getSimString* will return the empty string.

Note that calling these functions with control identifiers that do not belong to the currently active aircraft in DCS: World will result in undefined behavior (returning garbage data).

Refer to the next section for an example that uses the *getSimString* function.

Overriding Panel Data
---------------------

The DCS-BIOS Hub keeps two copies of export data. One is the *Sim Data* buffer which contains the most recent cockpit state received from DCS: World.
The other is the *Panel Data* buffer which contains the data that is sent to the serial ports.

When receiving new data from DCS: World, the following steps are executed:

* Copy the *Sim Data* buffer to the *Panel Data* buffer
* Execute all output callback functions
* Send the current state of the *Panel Data* buffer to the serial ports

The functions *hub.setPanelInteger* and *hub.setPanelString* can be used to overwrite data in the *Panel Buffer*.
The first parameter is a control identifier and the second is the new value.

For example, the following output callback will display the F-18C Hornet's UFC data on a simpit that was built for the AV8BNA Harrier::

local function remapOutput(a, b)
hub.setPanelString(b, hub.getSimString(a))
end

hub.registerOutputCallback(function()
local acftName = getSimString("MetadataStart/_ACFT_NAME")
if acftName == "FA-18C_hornet" then
remapOutput("FA-18C_hornet/UFC_COMM1_DISPLAY", "AV8BNA/UFC_COMM1_DISPLAY")
remapOutput("FA-18C_hornet/UFC_COMM2_DISPLAY", "AV8BNA/UFC_COMM2_DISPLAY")
local scratchpad = getSimString("FA-18C_hornet/UFC_SCRATCHPAD_STRING_1_DISPLAY")
scratchpad = scratchpad .. getSimString("FA-18C_hornet/UFC_SCRATCHPAD_STRING_2_DISPLAY")
scratchpad = scratchpad .. getSimString("FA-18C_hornet/UFC_SCRATCHPAD_NUMBER_DISPLAY")
setPanelString("AV8BNA/UFC_SCRATCHPAD", scratchpad)

remapOutput("FA-18C_hornet/UFC_OPTION_CUEING_1", "AV8BNA/AV8BNA_ODU_1_SELECT")
remapOutput("FA-18C_hornet/UFC_OPTION_DISPLAY_1", "AV8BNA/AV8BNA_ODU_1_Text")
remapOutput("FA-18C_hornet/UFC_OPTION_CUEING_2", "AV8BNA/AV8BNA_ODU_2_SELECT")
remapOutput("FA-18C_hornet/UFC_OPTION_DISPLAY_2", "AV8BNA/AV8BNA_ODU_2_Text")
remapOutput("FA-18C_hornet/UFC_OPTION_CUEING_3", "AV8BNA/AV8BNA_ODU_3_SELECT")
remapOutput("FA-18C_hornet/UFC_OPTION_DISPLAY_3", "AV8BNA/AV8BNA_ODU_3_Text")
remapOutput("FA-18C_hornet/UFC_OPTION_CUEING_4", "AV8BNA/AV8BNA_ODU_4_SELECT")
remapOutput("FA-18C_hornet/UFC_OPTION_DISPLAY_4", "AV8BNA/AV8BNA_ODU_4_Text")
remapOutput("FA-18C_hornet/UFC_OPTION_CUEING_5", "AV8BNA/AV8BNA_ODU_5_SELECT")
remapOutput("FA-18C_hornet/UFC_OPTION_DISPLAY_5", "AV8BNA/AV8BNA_ODU_5_Text")
end
end)

1 change: 1 addition & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ If you already know what you are looking for, use the search bar below the logo
hardware
code-snippets
lua-console
hub-scripts
6 changes: 5 additions & 1 deletion doc/lua-console.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ The Lua Console

The Lua Console page in the web interface allows you to execute snippets of Lua code in one of three different environments within DCS ("gui", "export" and "mission").

At the top of the screen are some status indicators; both have to be green for the feature to work.
You can also use it to debug your :doc:`hub-scripts` by choosing the "hub" environment.

At the top of the screen are some status indicators; both have to be green to execute code within DCS: World. To execute code in the "hub" environment, the DCS connection is not required.

.. image:: images/lua-console-indicators.png

If "DCS Connection" is not active, check that you have enabled the Lua Console in the :doc:`DCS Connection<dcs-connection>` page and that DCS: World is running. If "Enabled in Systray" is inactive, enable the Lua Console through the system tray menu.
Expand All @@ -17,6 +20,7 @@ To use the Lua Console:
The Environments
----------------

* "hub" executes code in the DCS-BIOS Hub itself. See the :doc:`hub-scripts` section for more information.
* "gui" executes the code in the same environment that the hook that implements the Lua Console is running in.
For more information about hooks, see "API\DCS_ControlAPI.html" in your DCS: World installation folder.
* "export" executes the code in the Export.lua environment. This is useful if you are developing a new module definition for DCS-BIOS.
Expand Down

0 comments on commit 21e288c

Please sign in to comment.