1. Do not share user accounts! Any account that is shared by another person will be blocked and closed. This means: we will close not only the account that is shared, but also the main account of the user who uses another person's account. We have the ability to detect account sharing, so please do not try to cheat the system. This action will take place on 04/18/2023. Read all forum rules.
    Dismiss Notice
  2. For downloading SimTools plugins you need a Download Package. Get it with virtual coins that you receive for forum activity or Buy Download Package - We have a zero Spam tolerance so read our forum rules first.

    Buy Now a Download Plan!
  3. Do not try to cheat our system and do not post an unnecessary amount of useless posts only to earn credits here. We have a zero spam tolerance policy and this will cause a ban of your user account. Otherwise we wish you a pleasant stay here! Read the forum rules
  4. We have a few rules which you need to read and accept before posting anything here! Following these rules will keep the forum clean and your stay pleasant. Do not follow these rules can lead to permanent exclusion from this website: Read the forum rules.
    Are you a company? Read our company rules

News New output possibilities for DCS

Discussion in 'Digital Combat Simulators (DCS)' started by RiftFlyer, Apr 28, 2017.

  1. Trip Rodriguez

    Trip Rodriguez VR Pilot

    Joined:
    May 8, 2016
    Messages:
    675
    Location:
    Lake Ariel, Pennsylvania
    Balance:
    3,920Coins
    Ratings:
    +330 / 6 / -0
    My Motion Simulator:
    6DOF
    LoGetAircraftDrawArgumentValue(104) should be all I need, thank you!

    We had it working for all other aircraft I've tested using strut compression. The Huey seemed to use a different draw argument ID (or whatever you call it) so I just needed to find what the correct value was. Thank you very much, that's fantastic!

    Trip
  2. Zed

    Zed VR Simming w/Reverb Gold Contributor

    Joined:
    Apr 4, 2017
    Messages:
    1,044
    Location:
    USA
    Balance:
    5,828Coins
    Ratings:
    +1,042 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    @BrassEm - Just digging into this and first off, that model viewer program is amazing! Thanks for that tip!

    But as I've been digging in and looking at yours and @Dirty's Export.lua, I've got some questions.

    I started mapping the argument values and ranges in the P-51 just since I'm familiar and did a quick check against another airplane and the don't seem to be the same values so is x in LoGetAircraftDrawArgumentValue(x) specific to each aircraft? For example, in the P-51d-25 edm file the canopy position is 162 but in the A10C edm file it is 7. Or am I looking at the wrong model files or something else? Both you and Dirty call using specific draw argument values as well as generic functions like LoGetIndicatedAirSpeed(). For an Export.lua file to be universal, if the numbers do map to different things in different aircraft, is there a mapping somewhere or is that what the generic functions do - map to generic things like indicated air speed from the model draw argument value for each specific aircraft?

    Your Export.lua has an if/else if bit that selects lurch values based on aircraft so it looks like your lua is intended to be universal?

    Where do I look to get a list of all the generic functions?

    In one of your posts here you said "Engine RPM might be not be a straight out LoGetRPM type function but part of a "LoGetEngine" function?"

    Is LoGetEngine a function that fills a structure? If so, is there a list of what those elements are and how to address them somewhere?

    I think I'm getting there but am just missing some information. Thanks in advance!

    And last, just to show how depraved this can get, as I was playing with the P-51 model I found the windscreen damage draw value - 413. As this grows from 0.000 to 1.000 you first get a hole in the left side of the windscreen and then an additional one on the right. I can rewrite a bit of the Arduino code to take either S codes or R and L codes where wind could even be specified for right and left fans to follow the holes in the windscreen or even apparent wind if it supports a vector as in a sideslip.

    I'm sure there will be more questions but I'm getting there. This all seems very powerful. It's just figuring out how to use that power.

    Thanks again to all who have paved this for us!
  3. Zed

    Zed VR Simming w/Reverb Gold Contributor

    Joined:
    Apr 4, 2017
    Messages:
    1,044
    Location:
    USA
    Balance:
    5,828Coins
    Ratings:
    +1,042 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    I may have my answer on the variable vs. structure question. In the example/reference Export.lua supplied with DCS, they have:

    local engine = LoGetEngineInfo()

    Which I think defines and fills "engine" and then various data in engine is referenced like so:

    default_output_file:write(string.format("t = %.2f ,RPM left = %f fuel_internal = %f \n",t,engine.RPM.left,engine.fuel_internal))

    So engine.RPM.left and engine.fuel_internal are specific variables in engine.

    I think.

    Another question - @Dirty, you used Extra1-3 to populate with WOW, IAS, and AOA. I've been using Game Dash which uses Dash1-Dash20. Anyone able to explain how I would make Game Dash aware of goings on in Export.lua? I'm looking for how it was done in sims that do support wind in Game Dash but I'm not finding anything yet.

    And I found a list of variables! DCSWorld/API/DCS_ControlAPI.html
  4. Dirty

    Dirty Well-Known Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    736
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    7,825Coins
    Ratings:
    +859 / 2 / -0
    I think so, yes. As far as I understood, if you want the Export.lua to be universal, you will have to check which aircraft type the player aircraft is, and then make a few If()'s or a switch() statement.

    It's great to see you getting creative with this :) That is exactly why I wanted to modify the original DCS plugin. Maybe I should rename the 3 parameters back to Extra1,2,3 to make it more obvious to users that these are there for the sole purpose of their personal enjoyment.:)

    If you want the quickest possible way to check if/what DCS is exporting, I made this DCS_Export_Server_Simple. It is just a console window that lets you see what DCS sends. You will have to use the Export.lua that comes with the repo and then make modifications as needed. Simtools' Export.lua will not work, because it uses TCP, not UDP.

    I will follow how this windiness-value goes. I might actually copy it :)

    Cheers
    • Informative Informative x 1
    Last edited: Jan 16, 2020
  5. Dirty

    Dirty Well-Known Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    736
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    7,825Coins
    Ratings:
    +859 / 2 / -0
    My suspicion is that some of the more generic functions are from back in the days when DCS was still "LockOn". I found some of them to be erroneous in anything other than a no-wind situation. I guess they keep them in there for legacy reasons, not sure though.

    Afaik, LoGetAircraftDrawArgumentValue(x) is the way to go and will work as long as the right parameter is known. :thumbs
    • Agree Agree x 1
  6. Zed

    Zed VR Simming w/Reverb Gold Contributor

    Joined:
    Apr 4, 2017
    Messages:
    1,044
    Location:
    USA
    Balance:
    5,828Coins
    Ratings:
    +1,042 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    Thanks @Dirty! I was trying to reconcile what I had found vs what you and @BrassEm were doing and try to sort out why. So you mostly fly just a few planes in DCS?

    I'm starting to get a bit addled having been diving deep in all this stuff but I don't remember there being a specific canopy variable mentioned. Maybe it's in one of the info structures. That would add just a minor abstraction but make a command universal instead of having to map each aircraft and update as new aircraft got added.

    I found the API documentation but do you know if there is anything that explains the variables in the info structures or does that fall out of the monitor application? Got it and thanks! Will explore!
  7. Zed

    Zed VR Simming w/Reverb Gold Contributor

    Joined:
    Apr 4, 2017
    Messages:
    1,044
    Location:
    USA
    Balance:
    5,828Coins
    Ratings:
    +1,042 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    @Dirty, one more question. Your experimental plugin was a .lua, a .dll. and a .jpg. Is there anything specific in that .dll that lets you have access to some variables and not others or is it the whole enchilada?

    And, It was bugging me. I went back through and found this post: https://www.xsimulator.net/community/threads/new-output-possibilities-for-dcs.10181/#post-179110

    Code:
    LoGetMechInfo() -- mechanization info
    result_is =
    {
        gear          = {status,value,main = {left = {rod},right = {rod},nose =  {rod}}}
        flaps          = {status,value}
        speedbrakes   = {status,value}
        refuelingboom = {status,value}
        airintake     = {status,value}
        noseflap      = {status,value}
        parachute     = {status,value}
        wheelbrakes   = {status,value}
        hook          = {status,value}
        wing          = {status,value}
        canopy        = {status,value}
        controlsurfaces = {elevator = {left,right},eleron = {left,right},rudder = {left,right}} -- relative vlues (-1,1) (min /max) (sorry:(
    } 
    That's exactly what I need! It can be universal unless I do things like map holes in the windscreen.

    Thanks again!
  8. Trip Rodriguez

    Trip Rodriguez VR Pilot

    Joined:
    May 8, 2016
    Messages:
    675
    Location:
    Lake Ariel, Pennsylvania
    Balance:
    3,920Coins
    Ratings:
    +330 / 6 / -0
    My Motion Simulator:
    6DOF
    That agrees with what I've seen looking at SimShaker code. Some things (mostly important functional stuff) is standardized.
    • Like Like x 1
  9. Trip Rodriguez

    Trip Rodriguez VR Pilot

    Joined:
    May 8, 2016
    Messages:
    675
    Location:
    Lake Ariel, Pennsylvania
    Balance:
    3,920Coins
    Ratings:
    +330 / 6 / -0
    My Motion Simulator:
    6DOF
    Ha! Now that's my kind of insanity!

    Just like I saw someone online say they got a CPAP machine from ebay to hook up to the oxygen switch and mask in their sim cockpit. I'll almost certainly be doing the same. =)

    I'm glad I'm not the only one!
    • Funny Funny x 3
  10. Zed

    Zed VR Simming w/Reverb Gold Contributor

    Joined:
    Apr 4, 2017
    Messages:
    1,044
    Location:
    USA
    Balance:
    5,828Coins
    Ratings:
    +1,042 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    I found the LoGetEngineInfo structure:

    Code:
    LoGetEngineInfo() -- (args - 0 ,results = table)
    engineinfo =
    {
        RPM = {left, right},(%)
        Temperature = { left, right}, (Celcium degrees)
        HydraulicPressure = {left ,right},kg per square centimeter
        FuelConsumption   = {left ,right},kg per sec
        fuel_internal      -- fuel quantity internal tanks    kg
        fuel_external      -- fuel quantity external tanks    kg
                
    }
    But I also found where there at least was a bug in that routine. Maybe fixed now - haven’t tried it yet to know. If the bug is still there, this won’t work.

    There's a workaround that will work, though. There was another comment on the Hoggit forum where someone had a workaround - just use the tachometer draw value - 0.000-1.000. I’ll have to map and do an if/then based on aircraft value to know RPM percentage, but that’s minor. At least I won’t need to do it for canopy too.

    The last bit is how to output values to Game Dash or where to find that? If other sims with wind using Game Dash and similar .lua structure, I can download the plugin and use the lua as a guide. Monkey see, monkey do. :)
    • Like Like x 1
  11. BrassEm

    BrassEm G-Seat + SFX100 Builder

    Joined:
    Apr 15, 2015
    Messages:
    120
    Location:
    NE of YMML
    Balance:
    1,040Coins
    Ratings:
    +47 / 0 / -0
    My Motion Simulator:
    DC motor, AC motor, 4DOF
    @Zed
    There were a few posts before I could answer. Sorry but trying to answer in point form as I read them.

    I am looking for a generic export.lua where I can jump into any aircraft and fly it without hassle. This will need a test for specific aircraft so that exact mechanics can be used. As per my example I did find different aircraft behaved very differently. (I have erased my model working notes per aircraft so as not to confuse the example I posted.)

    I would be using LoGetAircraftDrawArgumentValue(X) values for specific aircraft. It would be better to be specific rather than hope for a generic solution.

    Nice find with the windscreen damage draw value - 413. I hadn't got that far to see that damage modelling. There should also be a canopy jettison to account for as well. Another factor would be prop pitch? I would be consolidating these values in the export.lua so that your arduino Fan Control code can be generic and rely on standard values (0 - 2047?) they get fed.

    Another good find... local engine = LoGetEngineInfo()
    There is your RPM. But a bug?

    The answer is getting closer.
    • Like Like x 1
  12. Trip Rodriguez

    Trip Rodriguez VR Pilot

    Joined:
    May 8, 2016
    Messages:
    675
    Location:
    Lake Ariel, Pennsylvania
    Balance:
    3,920Coins
    Ratings:
    +330 / 6 / -0
    My Motion Simulator:
    6DOF
    That sounds like you are getting very close to the ejection seat motion cue trigger..... =D

    PS- Not to distract from the wind topic, but totally on topic for this thread: With all the things you guys are digging up here you've got me thinking. What kind of challenge would it be to put together really good .lua data for use with a scratch built custom control loading system for DCS? I'm talking Warbirds where you need both hands to pull the stick back during a steep dive kind of thing. =) Rudder loading. And everything else of course. This could be a dream come true IMO. Oh I can see my wallet trembling from across the room.
    • Agree Agree x 1
    Last edited: Jan 17, 2020
  13. BrassEm

    BrassEm G-Seat + SFX100 Builder

    Joined:
    Apr 15, 2015
    Messages:
    120
    Location:
    NE of YMML
    Balance:
    1,040Coins
    Ratings:
    +47 / 0 / -0
    My Motion Simulator:
    DC motor, AC motor, 4DOF
    That is on the agenda and it would definitely need its own thread. So much to do with so little spare time. :(
    • Like Like x 1
    • Agree Agree x 1
  14. Zed

    Zed VR Simming w/Reverb Gold Contributor

    Joined:
    Apr 4, 2017
    Messages:
    1,044
    Location:
    USA
    Balance:
    5,828Coins
    Ratings:
    +1,042 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    @BrassEm - On the P-51 I did find the canopy jettison lever, the canopy crank, and the canopy position itself in the draw values. (On a different computer or I'd quote them for the P-51 - started building the table on the 51 but stopped when everything was different on the A-10.) You’re looking for when canopies get jettisoned? I didn’t find that specifically but the canopy has both status and position in LoGetMechInfo():

    Code:
    LoGetMechInfo() -- mechanization info
    result_is =
    {
        gear          = {status,value,main = {left = {rod},right = {rod},nose =  {rod}}}
        flaps          = {status,value} 
        speedbrakes   = {status,value}
        refuelingboom = {status,value}
        airintake     = {status,value}
        noseflap      = {status,value}
        parachute     = {status,value}
        wheelbrakes   = {status,value}
        hook          = {status,value}
        wing          = {status,value}
        canopy        = {status,value}
        controlsurfaces = {elevator = {left,right},eleron = {left,right},rudder = {left,right}} -- relative vlues (-1,1) (min /max) (sorry:(
    } 
    I wonder if status on the canopy is if it was jettisoned or not? But if there is a jettison handle, that might also be useable for a canopy jettison cue?

    And I like your idea if I understand it correct - build a table ahead of values and just substitute in the proper values while calling the draw value functions?

    But that model viewer is trick! It crashes a lot but I’ve sort of figured out what not to do. The animate command is a bit weird since everything moves but also pretty cool.

    I'll start building the tables for all the planes. :)

    @BrassEm - do you know what the output command looks like so Game Dash can use the data?
    • Informative Informative x 1
  15. Trip Rodriguez

    Trip Rodriguez VR Pilot

    Joined:
    May 8, 2016
    Messages:
    675
    Location:
    Lake Ariel, Pennsylvania
    Balance:
    3,920Coins
    Ratings:
    +330 / 6 / -0
    My Motion Simulator:
    6DOF
    That's the absolute truth.
    • Agree Agree x 2
  16. Zed

    Zed VR Simming w/Reverb Gold Contributor

    Joined:
    Apr 4, 2017
    Messages:
    1,044
    Location:
    USA
    Balance:
    5,828Coins
    Ratings:
    +1,042 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    @Trip - my brother flew in the Air Force and for Southwest. I put him in my rig and he thought is was a good sim except for the lack of force feedback on the controls. They moved way too easy. With apparent wind and control position it wouldn’t be much of a trick at all to derive simulated control forces and feed those to another controller that provides physical resistance/restoring force to controls!

    But you are right - at least in DCS we have access to a treasure trove of information. As I was looking for stuff I found a page from 2018 that documents all kinds of things...

    There are some comments from the original document embedded in the code but what matters are the numbers. Also, it looks like they provide a way to reach back into the sim and move things from the outside and there is a structure for helicopters: LoGetHelicopterFMData()

    DCS Export Script
    Below is the source for the script responsible for exporting simulation information to the outside world. There's a lot of documentation and examples on how to use it within.

    Code:
    --- DO NOT EDIT.
    --- This file is for reference purposes only
    --- All user modifications should go to $HOME\Saved Games\DCS\Scripts\Export.lua
    
    -- Data export script for DCS, version 1.2.
    -- Copyright (C) 2006-2014, Eagle Dynamics.
    -- See http://www.lua.org for Lua script system info
    -- We recommend to use the LuaSocket addon (http://www.tecgraf.puc-rio.br/luasocket)
    -- to use standard network protocols in Lua scripts.
    -- LuaSocket 2.0 files (*.dll and *.lua) are supplied in the Scripts/LuaSocket folder
    -- and in the installation folder of the DCS.
    
    -- Expand the functionality of following functions for your external application needs.
    -- Look into Saved Games\DCS\Logs\dcs.log for this script errors, please.
    
    --[[   
    -- Uncomment if using Vector class from the Scripts\Vector.lua file
    local lfs = require('lfs')
    LUA_PATH = "?;?.lua;"..lfs.currentdir().."/Scripts/?.lua"
    require 'Vector'
    -- See the Scripts\Vector.lua file for Vector class details, please.
    --]]
    
    local default_output_file = nil
    
    function LuaExportStart()
    -- Works once just before mission start.
    -- Make initializations of your files or connections here.
    -- For example:
    -- 1) File
    --   default_output_file = io.open(lfs.writedir().."/Logs/Export.log", "w")
    -- 2) Socket
    --  package.path  = package.path..";"..lfs.currentdir().."/LuaSocket/?.lua"
    --  package.cpath = package.cpath..";"..lfs.currentdir().."/LuaSocket/?.dll"
    --  socket = require("socket")
    --  host = host or "localhost"
    --  port = port or 8080
    --  c = socket.try(socket.connect(host, port)) -- connect to the listener socket
    --  c:setoption("tcp-nodelay",true) -- set immediate transmission mode
    --
    --     local version = LoGetVersionInfo() --request current version info (as it showed by Windows Explorer fo DCS.exe properties)
    --    if version and default_output_file then
    --         
    --         default_output_file:write("ProductName: "..version.ProductName..'\n')
    --         default_output_file:write(string.format("FileVersion: %d.%d.%d.%d\n",
    --                                                 version.FileVersion[1],
    --                                                 version.FileVersion[2],
    --                                                 version.FileVersion[3],
    --                                                 version.FileVersion[4]))
    --         default_output_file:write(string.format("ProductVersion: %d.%d.%d.%d\n",
    --                                                 version.ProductVersion[1],
    --                                                 version.ProductVersion[2],
    --                                                 version.ProductVersion[3],  -- head  revision (Continuously growth)
    --                                                version.ProductVersion[4])) -- build number   (Continuously growth)   
    --    end
    
    end
    
    function LuaExportBeforeNextFrame()
    -- Works just before every simulation frame.
    
    -- Call Lo*() functions to set data to Lock On here
    -- For example:
    --    LoSetCommand(3, 0.25) -- rudder 0.25 right
    --    LoSetCommand(64) -- increase thrust
    
    end
    
    function LuaExportAfterNextFrame()
    -- Works just after every simulation frame.
    
    -- Call Lo*() functions to get data from Lock On here.
    -- For example:
    --    local t = LoGetModelTime()
    --    local name = LoGetPilotName()
    --    local altBar = LoGetAltitudeAboveSeaLevel()
    --    local altRad = LoGetAltitudeAboveGroundLevel()
    --    local pitch, bank, yaw = LoGetADIPitchBankYaw()
    --    local engine = LoGetEngineInfo()
    --    local HSI    = LoGetControlPanel_HSI()
    -- Then send data to your file or to your receiving program:
    -- 1) File
    -- if default_output_file then
    --      default_output_file:write(string.format("t = %.2f, name = %s, altBar = %.2f, altRad = %.2f, pitch = %.2f, bank = %.2f, yaw = %.2f\n", t, name, altBar, altRad, 57.3*pitch, 57.3*bank, 57.3*yaw))
    --      default_output_file:write(string.format("t = %.2f ,RPM left = %f  fuel_internal = %f \n",t,engine.RPM.left,engine.fuel_internal))
    --      default_output_file:write(string.format("ADF = %f  RMI = %f\n ",57.3*HSI.ADF,57.3*HSI.RMI))
    --    end
    -- 2) Socket
    --    socket.try(c:send(string.format("t = %.2f, name = %s, altBar = %.2f, alrRad = %.2f, pitch = %.2f, bank = %.2f, yaw = %.2f\n", t, name, altRad, altBar, pitch, bank, yaw)))
    
    end
    
    function LuaExportStop()
    -- Works once just after mission stop.
    -- Close files and/or connections here.
    -- 1) File
    if default_output_file then
        default_output_file:close()
        default_output_file = nil
    end
    -- 2) Socket
    --    socket.try(c:send("quit")) -- to close the listener socket
    --    c:close()
    end
    
    function LuaExportActivityNextEvent(t)
        local tNext = t
    
    -- Put your event code here and increase tNext for the next event
    -- so this function will be called automatically at your custom
    -- model times.
    -- If tNext == t then the activity will be terminated.
    
    -- For example:
    -- 1) File
    --  if default_output_file then
        --    local o = LoGetWorldObjects()
        --        for k,v in pairs(o) do
        --            default_output_file:write(string.format("t = %.2f, ID = %d, name = %s, country = %s(%s), LatLongAlt = (%f, %f, %f), heading = %f\n", t, k, v.Name, v.Country, v.Coalition, v.LatLongAlt.Lat, v.LatLongAlt.Long, v.LatLongAlt.Alt, v.Heading))
        --        end
        --    local trg = LoGetLockedTargetInformation()
        --  default_output_file:write(string.format("locked targets ,time = %.2f\n",t))
        --    for i,cur in pairs(trg) do
        --      default_output_file:write(string.format("ID = %d, position = (%f,%f,%f) , V = (%f,%f,%f),flags = 0x%x\n",cur.ID,cur.position.p.x,cur.position.p.y,cur.position.p.z,cur.velocity.x,cur.velocity.y,cur.velocity.z,cur.flags))
        --    end
        --    local route = LoGetRoute()
        --    default_output_file:write(string.format("t = %f\n",t))
        --    if route then
        --          default_output_file:write(string.format("Goto_point :\n point_num = %d ,wpt_pos = (%f, %f ,%f) ,next %d\n",route.goto_point.this_point_num,route.goto_point.world_point.x,route.goto_point.world_point.y,route.goto_point.world_point.z,route.goto_point.next_point_num))
        --          default_output_file:write(string.format("Route points:\n"))
        --        for num,wpt in pairs(route.route) do
        --          default_output_file:write(string.format("point_num = %d ,wpt_pos = (%f, %f ,%f) ,next %d\n",wpt.this_point_num,wpt.world_point.x,wpt.world_point.y,wpt.world_point.z,wpt.next_point_num))
        --        end
        --    end
    
        --    local stations = LoGetPayloadInfo()
        --    if stations then
        --        default_output_file:write(string.format("Current = %d \n",stations.CurrentStation))
    
        --        for i_st,st in pairs (stations.Stations) do
        --            local name = LoGetNameByType(st.weapon.level1,st.weapon.level2,st.weapon.level3,st.weapon.level4);
        --            if name then
        --            default_output_file:write(string.format("weapon = %s ,count = %d \n",name,st.count))
        --            else
        --            default_output_file:write(string.format("weapon = {%d,%d,%d,%d} ,count = %d \n", st.weapon.level1,st.weapon.level2,st.weapon.level3,st.weapon.level4,st.count))
        --            end
        --        end
        --    end
    
        --    local Nav = LoGetNavigationInfo()
        --    if Nav then
        --        default_output_file:write(string.format("%s ,%s  ,ACS: %s\n",Nav.SystemMode.master,Nav.SystemMode.submode,Nav.ACS.mode))
        --        default_output_file:write(string.format("Requirements :\n\t  roll %d\n\t pitch %d\n\t speed %d\n",Nav.Requirements.roll,Nav.Requirements.pitch,Nav.Requirements.speed))
        --    end
    --    end
    
    
    
    --    tNext = tNext + 1.0
    -- 2) Socket
    --    local o = LoGetWorldObjects()
    --    for k,v in pairs(o) do
    --      socket.try(c:send(string.format("t = %.2f, ID = %d, name = %s, country = %s(%s), LatLongAlt = (%f, %f, %f), heading = %f\n", t, k, v.Name, v.Country, v.Coalition, v.LatLongAlt.x, v.LatLongAlt.Long, v.LatLongAlt.Alt, v.Heading)))
    --    end
    --    tNext = tNext + 1.0
    
        return tNext
    end
    
    --[[
    
    -- Lock On supports Lua coroutines using internal LoCreateCoroutineActivity() and
    -- external CoroutineResume() functions. Here is an example of using scripted coroutine.
    
    Coroutines = {}    -- global coroutines table
    CoroutineIndex = 0    -- global last created coroutine index
    
    -- This function will be called by Lock On model timer for every coroutine to resume it
    function CoroutineResume(index, tCurrent)
        -- Resume coroutine and give it current model time value
        coroutine.resume(Coroutines[index], tCurrent)
        return coroutine.status(Coroutines[index]) ~= "dead"
        -- If status == "dead" then Lock On activity for this coroutine dies too
    end
    
    -- Coroutine function example using coroutine.yield() to suspend
    function f(t)
        local tNext = t
        local file = io.open("./Temp/Coroutine.log", "w")
        file:write(string.format("t = %f, started\n", tNext))
        tNext = coroutine.yield()
        for i = 1,10 do
            file:write(string.format("t = %f, continued\n", tNext))
            tNext = coroutine.yield()
        end
        file:write(string.format("t = %f, finished\n", tNext))
        file:close()
    end
    
    -- Create your coroutines and save them in Coriutines table, e.g.:
    CoroutineIndex = CoroutineIndex + 1
    Coroutines[CoroutineIndex] = coroutine.create(f)
    
    -- Use LoCreateCoroutineActivity(index, tStart, tPeriod) to plan your coroutines
    -- activity at model times, e.g.:
    LoCreateCoroutineActivity(CoroutineIndex, 1.0, 3.0) -- to start at 1.0 second with 3.0 seconds period
    -- Coroutine output in the Coroutine.log file:
    -- t = 1.000000, started
    -- t = 4.000000, continued
    -- t = 7.000000, continued
    -- t = 10.000000, continued
    -- t = 13.000000, continued
    -- t = 16.000000, continued
    -- t = 19.000000, continued
    -- t = 22.000000, continued
    -- t = 25.000000, continued
    -- t = 28.000000, continued
    -- t = 31.000000, continued
    -- t = 34.000000, finished
    --]]
    
    --[[ You can use registered Lock On internal data exporting functions in this script
    and in your scripts called from this script.
    
    Note: following functions are implemented for exporting technology experiments only,
    so they may be changed or removed in the future by developers.
    
    All returned values are Lua numbers if not pointed other type.
    
    Output:
    LoIsObjectExportAllowed() -- returns true if world objects data is available
    LoIsSensorExportAllowed() -- returns true if radar/targets data is available
    LoIsOwnshipExportAllowed() -- true if ownship data is available
    
    LoGetModelTime() -- returns current model time (args - 0, results - 1 (sec))
    LoGetMissionStartTime() -- returns mission start time (args - 0, results - 1 (sec))
    LoGetPilotName() -- (args - 0, results - 1 (text string))
    LoGetPlayerPlaneId() -- (args - 0, results - 1 (number))
    LoGetIndicatedAirSpeed() -- (args - 0, results - 1 (m/s))
    LoGetTrueAirSpeed() -- (args - 0, results - 1 (m/s))
    LoGetAltitudeAboveSeaLevel() -- (args - 0, results - 1 (meters))
    LoGetAltitudeAboveGroundLevel() -- (args - 0, results - 1 (meterst))
    LoGetAngleOfAttack() -- (args - 0, results - 1 (rad))
    LoGetAccelerationUnits() -- (args - 0, results - table {x = Nx,y = NY,z = NZ} 1 (G))
    LoGetVerticalVelocity()  -- (args - 0, results - 1(m/s))
    LoGetMachNumber()        -- (args - 0, results - 1)
    LoGetADIPitchBankYaw()   -- (args - 0, results - 3 (rad))
    LoGetMagneticYaw()       -- (args - 0, results - 1 (rad)
    LoGetGlideDeviation()    -- (args - 0,results - 1)( -1 < result < 1)
    LoGetSideDeviation()     -- (args - 0,results - 1)( -1 < result < 1)
    LoGetSlipBallPosition()  -- (args - 0,results - 1)( -1 < result < 1)
    LoGetBasicAtmospherePressure() -- (args - 0,results - 1) (mm hg)
    LoGetControlPanel_HSI()  -- (args - 0,results - table)
    result =
    {
        ADF_raw, (rad)
        RMI_raw, (rad)
        Heading_raw, (rad)
        HeadingPointer, (rad)
        Course, (rad)
        BearingPointer, (rad)
        CourseDeviation, (rad)
    }
    LoGetEngineInfo() -- (args - 0 ,results = table)
    engineinfo =
    {
        RPM = {left, right},(%)
        Temperature = { left, right}, (Celcium degrees)
        HydraulicPressure = {left ,right},kg per square centimeter
        FuelConsumption   = {left ,right},kg per sec
        fuel_internal      -- fuel quantity internal tanks    kg
        fuel_external      -- fuel quantity external tanks    kg
                
    }
    
    LoGetRoute()  -- (args - 0,results = table)
    get_route_result =
    {
        goto_point, -- next waypoint
        route       -- all waypoints of route (or approach route if arrival or landing)
    }
    waypoint_table =
    {
        this_point_num,        -- number of point ( >= 0)
        world_point = {x,y,z}, -- world position in meters
        speed_req,             -- speed at point m/s
        estimated_time,        -- sec
        next_point_num,           -- if -1 that's the end of route
        point_action           -- name of action "ATTACKPOINT","TURNPOINT","LANDING","TAKEOFF"
    }
    LoGetNavigationInfo() (args - 0,results - 1( table )) -- information about ACS
    get_navigation_info_result =
    {
        SystemMode = {master,submode}, -- (string,string) current mode and submode
    --[=[
        master values (depend of plane type)
                    "NAV"  -- navigation
                    "BVR"  -- beyond visual range AA mode
                    "CAC"  -- close air combat               
                    "LNG"  -- longitudinal mode
                    "A2G"  -- air to ground
                    "OFF"  -- mode is absent
        submode values (depend of plane type and master mode)
        "NAV" submodes
        {
            "ROUTE"
            "ARRIVAL"
            "LANDING"
            "OFF"
        }
        "BVR" submodes
        {
            "GUN"   -- Gunmode
            "RWS"   -- RangeWhileSearch
            "TWS"   -- TrackWhileSearch
            "STT"   -- SingleTrackTarget (Attack submode)
            "OFF"
        }
        "CAC" submodes
        {
            "GUN"
            "VERTICAL_SCAN"
            "BORE"
            "HELMET" 
            "STT"
            "OFF"
        }
        "LNG" submodes
        {
            "GUN"
            "OFF"
            "FLOOD"  -- F-15 only
        }
        "A2G" submodes
        {
            "GUN"
            "ETS"       -- Emitter Targeting System On
            "PINPOINT" 
            "UNGUIDED"  -- unguided weapon (free fall bombs, dispensers , rockets)
            "OFF"
        }
    --]=]
        Requirements =  -- required parameters of flight
        {
            roll,       -- required roll,pitch.. , etc.
            pitch,       
            speed,   
            vertical_speed,
            altitude,
        }
        ACS =   -- current state of the Automatic Control System
        {
            mode = string ,
            --[=[
                mode values  are :     
                        "FOLLOW_ROUTE",
                        "BARO_HOLD",         
                        "RADIO_HOLD",       
                        "BARO_ROLL_HOLD",     
                        "HORIZON_HOLD",   
                        "PITCH_BANK_HOLD",
                        "OFF"
            --]=]
            autothrust , -- 1(true) if autothrust mode is on or 0(false) when not; 
        }
    }
    LoGetMCPState() -- (args - 0, results - 1 (table of key(string).value(boolean))
        returned table keys for LoGetMCPState():
            "LeftEngineFailure"
            "RightEngineFailure"
            "HydraulicsFailure"
            "ACSFailure"
            "AutopilotFailure"
            "AutopilotOn"
            "MasterWarning"
            "LeftTailPlaneFailure"
            "RightTailPlaneFailure"
            "LeftAileronFailure"
            "RightAileronFailure"
            "CanopyOpen"
            "CannonFailure"
            "StallSignalization"
            "LeftMainPumpFailure"
            "RightMainPumpFailure"
            "LeftWingPumpFailure"
            "RightWingPumpFailure"
            "RadarFailure"
            "EOSFailure"
            "MLWSFailure"
            "RWSFailure"
            "ECMFailure"
            "GearFailure"
            "MFDFailure"
            "HUDFailure"
            "HelmetFailure"
            "FuelTankDamage"
    LoGetObjectById() -- (args - 1 (number), results - 1 (table))
    Returned object table structure:
    {
        Name =
        Type =  {level1,level2,level3,level4},  ( see Scripts/database/wsTypes.lua) Subtype is absent  now
        Country   =   number ( see Scripts/database/db_countries.lua
        Coalition =
        CoalitionID = number ( 1 or 2 )
        LatLongAlt = { Lat = , Long = , Alt = }
        Heading =   radians
        Pitch      =   radians
        Bank      =  radians
        Position = {x,y,z} -- in internal DCS coordinate system ( see convertion routnes below)
        -- only for units ( Planes,Hellicopters,Tanks etc)
        UnitName    = unit name from mission (UTF8) 
        GroupName = unit name from mission (UTF8)
            Flags = {
            RadarActive = true if the unit has its radar on
            Human = true if the unit is human-controlled
            Jamming = true if the unit uses EMI jamming
            IRJamming = -- same for IR jamming
            Born = true if the unit is born (activated)
            AI_ON = true if the unit's AI is active
            Invisible = true if the unit is invisible
            Static - true if the unit is a static object
            }
    }
    
    continued...
    • Like Like x 1
  17. Zed

    Zed VR Simming w/Reverb Gold Contributor

    Joined:
    Apr 4, 2017
    Messages:
    1,044
    Location:
    USA
    Balance:
    5,828Coins
    Ratings:
    +1,042 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    Should have made it a plain text file... it was too big to fit in a message. Here’s the whole thing.

    Attached Files:

    • Like Like x 2
  18. Trip Rodriguez

    Trip Rodriguez VR Pilot

    Joined:
    May 8, 2016
    Messages:
    675
    Location:
    Lake Ariel, Pennsylvania
    Balance:
    3,920Coins
    Ratings:
    +330 / 6 / -0
    My Motion Simulator:
    6DOF
    Great stuff, the possibilities do seem to be endless. I'm really glad we've got you guys digging into this. Think just one year ago everyone was settling for telemetry that was a total mess when you pitched past vertical or rolled through inverted. Now we've got that fixed and so much more in the works. It's not like it's a new game, it was stagnant for years. I'm glad I came into it when I did!

    I see hydraulic failure there. That's one of the things I want to simulate with control loading in the Huey!

    The #1 thing I would really like us to find is data for fixed wing like that one for helicopters that gives the G-force effects on the pilot instead of the aircraft. That takes so much guesswork out of the motion cues! Not that I've properly tested it, but in theory. I'm hoping that soon I'll finally be flying instead of just building and modifying. One more good day with Fusion 360 and I think I'll be ready to start construction on the new simulator.

    I very much look forward to the evolution of the things we are discussing here!
    • Like Like x 2
  19. Zed

    Zed VR Simming w/Reverb Gold Contributor

    Joined:
    Apr 4, 2017
    Messages:
    1,044
    Location:
    USA
    Balance:
    5,828Coins
    Ratings:
    +1,042 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    I totally agree, Trip. I’ve got a stick extension on my Warthog and was trying to figure how to simulate stick forces. It’s off topic for this thread but since it was mentioned, control surfaces would all stiffen as speed increases so I’m thinking something like the collective linkage on a helicopter with springs (and bearings) to push against the stick. When low on the stick the restoring forces are small and the stick is floppy. Raise it up the stick and you have less leverage so centering forces go up. Nothing complicated, just a mechanism to raise and lower the centering mechanism up and down the base of the stick. My stick is floor mounted on my upper frame so I have room to do that. Some bellcranks or even bowden cables could be used to turn a linear horizontal movement to be a vertical one. Wouldn’t be expensive either. :)
    • Useful Useful x 1
  20. Dirty

    Dirty Well-Known Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    736
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    7,825Coins
    Ratings:
    +859 / 2 / -0
    That was my plan when I started playing with Arduinos in late 2017. You can send the relevant data directly to an Arduino that has an Ethernet shield.
    1_-_RIG_2017-Dec-05_02-52-57PM-000_CustomizedView21281235124.png

    Cheers,... Dirty
    • Like Like x 1
    • Winner Winner x 1