Экспорт данных из DCS КА-50 — «Железные» кокпиты

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

Патч можно скачать отсюда: http://www.digitalco…roducts&lang=ru
Ветка на официальном форуме: http://forums.eagle….ead.php?t=44017

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

Сообщение отредактировано LISА: 11 January 2012 — 19:33


Ответов: 19

Начнем с того что в DCS, так же как и в LO данные экспортируются по протоколу ТСР.
Не буду подробно останавливаться на особенностях работы ТСР, скажу только что
для того что бы данные начали отправляться, должна быть запущена программа которая
сначала создаст сервер(ведущий процесс), а сам DCS является ведомым процессом.

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

Что бы включить экспорт нужно найти файл Config.lua (…KA50ConfigExportConfig.lua)
и немного подредактировать, должно быть так:

EnableExportScript = true

Далее речь будет идти о lua скриптах.
На официальном форуме ED есть ветка посвященная lua и
экспорту данных: http://forums.eagle….ead.php?t=33051
Wiki: http://en.wiki.eagle…ki/Export_1_0_1
Еще про lua: http://www.digitalco…default&lang=ru

Сообщение отредактировано LISА: 02 September 2009 — 03:12

Больше всего нам интересен файл Export.lua (…KA50ConfigExportExport.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

Сообщение отредактировано LISА: 01 September 2009 — 16:16

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

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

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

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

Сообщение отредактировано LISА: 02 September 2009 — 03:13

:sarcastic: to be continued….

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

01.jpg

Сообщение отредактировано LISА: 03 September 2009 — 00:13

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

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

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

Если нет, изучаем файл Error.log (…KA50TempError.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)

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

Сообщение отредактировано LISА: 01 September 2009 — 22:38

Теперь самое вкусное, доступ к данным :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 (…KA50ScriptsAircraftsKa-50Cockpitmainpanel_init.lua)
Имя переменной (pitch, roll) можно придумать свое.

Возвращает флоат, причем как 0—1 так и -1—1, единицы измерения
в большинстве случаев попугаи, шкалы НЕЛИНЕЙНЫЕ.

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

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

———————————————

СПИСКИ ДАННЫХ ПО ПРИБОРАМ И ЛАМПАМ
залил сюда: http://ifolder.ru/13807475

Сообщение отредактировано LISА: 02 September 2009 — 22:25

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

Еще по экспорту, страничка на вики: http://en.wiki.eagle…ki/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

ЭКРАН

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

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

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

В экспорте мы можем получить как переменные в чистом виде
так и аргументы отрисовки, те то что показывают приборы в вирт. кабине.

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

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)

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

Теперь о грустном, сейчас в экспорте нельзя получить:
— данные с цифрового табло УВ-26 отстрел ЛТЦ
— данные с ПВИ пульт ввода и индикации

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

Есть еще более простой способ поэкспериментировать с экспортом,
особенно если программы для приема данных нет, можно записывать
данные в лог. Скрипт выглядит примерно так:

-- тут указываем, что данные нужно записать в файл
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,курс = %fn",roll,pith,heading)) -- записываем в файл
  ------------------------------------------------------
  return tNext
end

результат смотрим в файле Export.log (…KA50TempExport.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
.....

УФ! прямо таки небольшая статья получилась)
нужно сказать отдельное спасибо Alex O’kean
из команды ED за реализацию экспорта

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

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

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