Jump to content

Archived

This topic is now archived and is closed to further replies.

LISА

Экспорт данных из DCS КА-50

Recommended Posts

Совсем недавно вышел патч для DCS КА-50, в котором реализован полноценный экспрот данных.

 

Патч можно скачать отсюда: http://www.digitalco...roducts〈=ru

Ветка на официальном форуме: http://forums.eagle....ead.php?t=44017

 

В этой ветке обсуждаем особенности экспорта.

Share this post


Link to post
Share on other sites

Начнем с того что в DCS, так же как и в LO данные экспортируются по протоколу ТСР.

Не буду подробно останавливаться на особенностях работы ТСР, скажу только что

для того что бы данные начали отправляться, должна быть запущена программа которая

сначала создаст сервер(ведущий процесс), а сам DCS является ведомым процессом.

 

В моем случае данные принимаются с помощю ПСС от KOIS (см. ветку "отживление приборов")

 

Что бы включить экспорт нужно найти файл Config.lua (...KA50\Config\Export\Config.lua)

и немного подредактировать, должно быть так:

 

EnableExportScript = true

Share this post


Link to post
Share on other sites

Далее речь будет идти о lua скриптах.

На официальном форуме ED есть ветка посвященная lua и

экспорту данных: http://forums.eagle.ru/showthread.php?t=33051

Wiki: http://en.wiki.eagle...ki/Export_1_0_1

Еще про lua: http://www.digitalcombatsimulator.com/index.php?end_pos=567&scr=default〈=ru

Share this post


Link to post
Share on other sites

Больше всего нам интересен файл Export.lua (...KA50\Config\Export\Export.lua)

Рассмотрим основные куски кода:

 

function LuaExportStart()
 package.path  = package.path..";.\\LuaSocket\\?.lua"
 package.cpath = package.cpath..";.\\LuaSocket\\?.dll"
 socket = require("socket")
 host = host or "localhost"
 port = port or 8080
 c = socket.try(socket.connect(host, port))
 c:setoption("tcp-nodelay",true)
end

 

тут натраивается TCP

далее:

 

 

function LuaExportBeforeNextFrame()
 .......
end

function LuaExportAfterNextFrame()
 .......
end

 

тут думаю все понятно, внутри этих конструкций можно

писать код, который будет выполнятся до или после следующего

кадра

 

ну и на последок:

 

function LuaExportStop()
 socket.try(c:send("quit"))
 c:close()
end

Share this post


Link to post
Share on other sites

можно еще добавить такую конструкцию и тогда можно

будет выполнять код через определенный интервал времени

без привязки к fps

 

function LuaExportActivityNextEvent(t)
 local tNext = t
 ......
 tNext = tNext + 0.1  --  сдесь задается временнной интервал в секундах 
 return tNext
end

Share this post


Link to post
Share on other sites

Простейший скрипт экспорта выглядит так:

 

function LuaExportStart()
 package.path  = package.path..";.\\LuaSocket\\?.lua"
 package.cpath = package.cpath..";.\\LuaSocket\\?.dll"
 socket = require("socket")
 host = host or "localhost"
 port = port or 8080
 c = socket.try(socket.connect(host, port))
 c:setoption("tcp-nodelay",true)
end

function LuaExportBeforeNextFrame()
end

function LuaExportAfterNextFrame()                  
 local TAS = LoGetTrueAirSpeed() * 3.6             -- получаем значение истинной скорости
 socket.try(c:send(string.format("A  %s \n",TAS))) -- отправляем данные
end

function LuaExportStop()
socket.try(c:send("quit"))
c:close()
end

Share this post


Link to post
Share on other sites

socket.try(c:send(string.format("A  %s \n",TAS)))

 

Эта строчка может выглядеть подругому, в зависимости от того

что и в каком виде нужно отправить, в данном случае отправляется

только одно значение истинной скорости.

 

Запускаем программу сервер, запускаем DCS и если все сделано

правильно, данные будут экспортироваться.

 

Если нет, изучаем файл Error.log (...KA50\Temp\Error.log)

например:

 

Lua::Config::call error LuaExportAfterNextFrame:./Config/Export/Export.lua:150: bad argument #21 to 'format' (number expected, got nil)

 

строка 150, ожидаем числовое значение а получаем пустое место (nil)

 

Lua::Config::call error LuaExportStart:(null)

 

Если видим такую строчку, значит не запущена или не корректоно

работает программа сервер.

Share this post


Link to post
Share on other sites

Теперь самое вкусное, доступ к данным :sarcastic:

 

Есть несколько способов получить значение, старый

способ выглядит так:

 

local TAS = LoGetTrueAirSpeed()*3.6
local H = LoGetAltitudeAboveSeaLevel()
local pitch, bank, yaw = LoGetADIPitchBankYaw()
и тд.....

 

Эти функции остались еще со времен LO, возвращают

переменные в чистом виде (единицы имерения метры,

км/ч, радианы) шкалы линейные.

 

На самом деле старых функций много, однако большинство

функций из LO в DCS уже не работают!

 

--------------------------------------------------------

 

С выходом патча 1.01 стал доступен другой способ получения данных:

 

dofile("Scripts/Aircrafts/Ka-50/Cockpit/devices.lua")

 local panel = GetDevice(0)
    if panel then
       panel :update_arguments()

       local roll = panel:get_argument_value(100)
       local pitch = panel:get_argument_value(101)
  end

 

GetDevice(0) это запрос девайса за номером 0. По умолчанию за номером 0

закреплена сама кабина (вернее то устройство которое отвечает за отрисовку кабины)

 

Почти все что шевелится в кабине, включая рычаги управления есть экспорте.

Главное правильно указать номер аргумента! Номера аргументов можно посмотреть

в файле mainpanel_init.lua (...KA50\Scripts\Aircrafts\Ka-50\Cockpit\mainpanel_init.lua)

Имя переменной (pitch, roll) можно придумать свое.

 

Возвращает флоат, причем как 0---1 так и -1---1, единицы измерения

в большинстве случаев попугаи, шкалы НЕЛИНЕЙНЫЕ.

 

Нужно понимать что мы имеем дело не с переменными в чистом виде, а с

аргументами отрисовки, те 0 и 1 соответсвуют двум крайним положениям

стелки на приборе.

 

С сигнальными лампами все просто 0 не горит, 1 горит код тот же

Для кнопок со световой индикацией, тоже есть данные.

 

---------------------------------------------

 

СПИСКИ ДАННЫХ ПО ПРИБОРАМ И ЛАМПАМ

залил сюда: http://ifolder.ru/13807475

Share this post


Link to post
Share on other sites

и это еще не все...

Share this post


Link to post
Share on other sites

Еще по экспорту, страничка на вики: http://en.wiki.eagle.ru/wiki/Export_1_0_1

 

Далее, СУО

 

  local weapon_system = GetDevice(devices.WEAP_INTERFACE)
    if weapon_system then
    W1 = weapon_system:get_weapon_type_on_station(0-3) -- тип снаряда, строка "9A4172","S-13"","EMPTY"  
    W2 = weapon_system:get_weapon_count_on_station(0-3) -- число снарядов, число 0-40 шт
    W3 = weapon_system:get_selected_weapon_stations() -- выбранные пилоны, таблица  0 1, 2 3 
    W4 = weapon_system:get_selected_gun_ammo() -- строка "НЕ" или "АР"
    W5 = weapon_system:get_selected_gun_ammo_count() -- остаток боекомплекта пушки, число 0-240 шт
   end

 

пример кода

 

local weapon_system = GetDevice(12)--devices["WEAP_INTERFACE"]
if weapon_system then
    local selected_stations = weapon_system:get_selected_weapon_stations()
	local s = " "	
	for i,o in ipairs(selected_stations) do	
		s = s..tostring(o).." "
	end
end

Share this post


Link to post
Share on other sites

ЭКРАН

 

local ekran = GetDevice(devices.EKRAN_32_03)
if ekran then
  txt = ekran:get_actual_text_frame()
end

 

 

радиовысотомер

 

local raltimeter = GetDevice(devices.RADAR_ALTIMETER)

if raltimeter then
 R1 = raltimeter:get_needle_value() -- число, 0-35000см!
 R2 = raltimeter:get_dangerous_height() -- число, 0-35000см!
 R3 = raltimeter:get_dangerous_height_flag() --  
 R4 = raltimeter:get_warning_flag() --  
end

Share this post


Link to post
Share on other sites

значения перегрузки в кабине:

 

  local fm_data = LoGetHelicopterFMData()
A1 = fm_data.G_factor    -- вектор перегрузки в кокпите
A2 = fm_data.speed       -- вектор скорости в мировой СК
A3 = fm_data.acceleration     -- вектор ускорений в мировой СК
A4 = fm_data.angular_speed    -- вектор угловой скорости
A5 = fm_data.angular_acceleration -- вектор углового ускорения
A6 = fm_data.yaw 
A7 = fm_data.pitch  
A8 = fm_data.roll 

Share this post


Link to post
Share on other sites

Принимаем данные:

 

post-45226-125192239878_thumb.jpg

Share this post


Link to post
Share on other sites

В экспорте мы можем получить как переменные в чистом виде

так и аргументы отрисовки, те то что показывают приборы в вирт. кабине.

 

Например крен-тангаж:

 

local pitch, bank, yaw = LoGetADIPitchBankYaw()

 

крен-тангаж который показывает ИКП:

 

roll = panel:get_argument_value(100)
pitch = panel:get_argument_value(101)

 

крен-тангаж резервный АГД:

 

re_roll = panel:get_argument_value(142)
re_pitch = panel:get_argument_value(143)

 

Резервный АГД может сбиваеться, дрейф, отказы

гировертикали и тд, все это экспортируется.

Share this post


Link to post
Share on other sites

Теперь о грустном, сейчас в экспорте нельзя получить:

- данные с цифрового табло УВ-26 отстрел ЛТЦ

- данные с ПВИ пульт ввода и индикации

 

Возможно с выходом новой части DCS, что то изменится.

Share this post


Link to post
Share on other sites

Есть еще более простой способ поэкспериментировать с экспортом,

особенно если программы для приема данных нет, можно записывать

данные в лог. Скрипт выглядит примерно так:

 

-- тут указываем, что данные нужно записать в файл
function LuaExportStart()
 local file = io.open("./Temp/Export.log", "w")
 if file then
io.output(file)
 end
end

function LuaExportBeforeNextFrame()
end

function LuaExportAfterNextFrame()
end

function LuaExportStop()
   io.close()
end

-- получаем данные c интервалом 1 сек.
function LuaExportActivityNextEvent(t)
 local tNext = t
 tNext = tNext + 1.0 -- тут устаавливается итервал

 if not LoGetPlayerPlaneId() then return t end
 ------------------------------------------------------

 dofile("Scripts/Aircrafts/Ka-50/Cockpit/devices.lua")
 local panel = GetDevice(0)
    if panel then
       panel :update_arguments()

       roll = panel:get_argument_value(100)*90  -- крен
       pith = panel:get_argument_value(101)*180  -- тангаж
       heading = panel:get_argument_value(112)*360  -- курс
 end

 io.write(string.format("крен = %f,тангаж = %f,курс = %f\n",roll,pith,heading)) -- записываем в файл
 ------------------------------------------------------
 return tNext
end

 

результат смотрим в файле Export.log (...KA50\Temp\Export.log)

 

 

крен = -0.042383,тангаж = 2.861339,курс = 246.514256
крен = -3.397625,тангаж = 5.704337,курс = 252.353790
крен = -2.945700,тангаж = 5.545237,курс = 258.206220
крен = -1.579102,тангаж = 6.352402,курс = 261.492248
.....

Share this post


Link to post
Share on other sites

УФ! прямо таки небольшая статья получилась)

нужно сказать отдельное спасибо Alex O'kean

из команды ED за реализацию экспорта

Share this post


Link to post
Share on other sites

Кроме экспорта, есть еще ввод данных, тут тоже все в порядке,

описывать не буду, подробно можно почитать тут:

 

http://freemanru.spaces.live.com/blog/cns!9E1589588902DBAA!351.entry

http://freemanru.spaces.live.com/blog/cns!9E1589588902DBAA!360.entry

Share this post


Link to post
Share on other sites

что то я смотрю тема вертушек не очень популярна...

Share this post


Link to post
Share on other sites

что то я смотрю тема вертушек не очень популярна...

 

я бы поддержал, но сейчас на первом месте МиГ...

 

Да и комп у меня не тянет этот сим :)

Share this post


Link to post
Share on other sites

Экспорт данных из DCS КА-50

ЧАСТЬ ВТОРАЯ DCS+SIOC

 

Роутер ПСС Андрея Зверева к сожалению канул в лету, что делать, пришлось искать

другой способ передачи данных. Выбор пал на SIOC тем более что Иван (Sly)

написал клиента для работы с платами Сергея (САБ) клиент называется "Авиатор"

 

Забегая вперед, скажу что сам SIOC используется исключительно как сервер

на который DCS отправляет данные, а "Авиатор" их тут же вылавливает.

Всю работу по приведению переменных в "удобный" вид делаем средствами lua скриптов.

Share this post


Link to post
Share on other sites

Для начала пару слов о SIOC, его нужно просто скачать и установить,

все настройки по умолчанию, файл sioc.ssi пустой. Этого пока достаточно.

 

В строчке "Clients connecteds" можно увидеть сколько клиентов подключены,

можно так же запустить IOCPConsole, и посмотреть какие данные приходят.

 

sioc.jpg

Share this post


Link to post
Share on other sites

Далее о lua скриптах напоминаю основные моменты:

 

Чтобы включить экспорт нужно подредактировать файл Config.lua

(...KA50\Config\Export\Config.lua) EnableExportScript = true

 

После чего редактируем файл Export.lua (...KA50\Config\Export\Export.lua)

тут пишется основной кусок кода.

 

Данные можно получить как в обычных величинах(метры) так и в виде аргумента отрисовки.

в последнем случае 0(или -1) будет соответствовать началу шкалы, а +1 концу шкалы.

обычно я перемножаю аргументы отрисовки на 1024, и в таком виде отправляю.

 

Пример рабочего lua скрипта, который получает значение радиовысоты:

 

-----------------------------------------------------------
-- процедуры открытия порта
-- значения "host" и "port" по умолчанию для SIOC
function LuaExportStart()
   package.path  = package.path..";.\\LuaSocket\\?.lua"
   package.cpath = package.cpath..";.\\LuaSocket\\?.dll"

   socket = require("socket")
   host = "127.0.0.1"
   port = 8092
   c = socket.try(socket.connect(host, port))
   c:setoption("tcp-nodelay",true)
   c:settimeout(.01)
end
-- эта функция выполняется после отрисовки каждого кадра
function LuaExportAfterNextFrame()
   local lSIOC_SendString = ""
   dofile("Scripts/Aircrafts/Ka-50/Cockpit/devices.lua")
   -- тут получаем данные по радиовысотомеру
   local raltimeter = GetDevice(38)
   if raltimeter then
   R1 = raltimeter:get_needle_value() -- получаем значение в метрах
   end
   -- округляем значение до целого
   R1 = math.floor(R1 + 0.5)
   -- формируем строчку номер переменной = значение
   R1 = "2="..R1..":"
   -- записываем строчку
   lSIOC_SendString = lSIOC_SendString..R1
   -- отправляем
   if lSIOC_SendString ~= "" then
    socket.try(c:send("Arn.Resp:"..lSIOC_SendString.."\n"))
   end
end
-- процедуры закрытия порта
function LuaExportStop()
   io.close()
   socket.try(c:send("quit")) -- to close the listener socket
   c:close()
end

Share this post


Link to post
Share on other sites

Немного разберем скрипт:

 

Получение данных в основном остается как и было.

за исключением того что SIOC ожидает переменных в виде строки

номер переменной = значение переменной

R1 = "2="..R1..":"

 

Кроме того полученную переменную нужно обязательно округлить!!!

R1 = math.floor(R1 + 0.5)

 

Записать в таблицу и отправить

lSIOC_SendString = lSIOC_SendString..R1
if lSIOC_SendString ~= "" then
		socket.try(c:send("Arn.Resp:"..lSIOC_SendString.."\n"))

 

Я еще забыл строчку, которая принудительно обноляет переменные

даже если кокпит не отрисовывается, например на внешнем виде:

  panel :update_arguments()

Share this post


Link to post
Share on other sites

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...