Jump to content

gyrovague

3rd Party Developers
  • Posts

    189
  • Joined

  • Last visited

Everything posted by gyrovague

  1. Assuming you're using SFM, what you can do is this: change your joystick.lua: {combos = defaultDeviceAssignmentFor("rudder"), action = iCommandPlaneRudder , name = _('Rudder')} and keyboard.lua: {combos = {{key = 'Z'}}, down = iCommandPlaneLeftRudderStart, up = iCommandPlaneLeftRudderStop, name = _('Aircraft Rudder Left'), category = _('Flight Control')}, {combos = {{key = 'X'}}, down = iCommandPlaneRightRudderStart, up = iCommandPlaneRightRudderStop, name = _('Aircraft Rudder Right'), category = _('Flight Control')}, to use other custom command values for the up,down,action values ... then in your code, catch those custom command values (with listen_command and the SetCommand callback), and pass them onto DCS SFM as desired (scaled or whatever) using dispatch_action, e.g. dispatch_action(nil, iCommandPlaneRudder, yourvalue) You may have to define iCommandPlaneRudder as a local variable with the correct value,e.g. local iCommandPlaneRudder = 2003 (see https://forums.eagle.ru/attachment.php?attachmentid=106386&d=1414456928 ) For the Z X keys, you'll have to (probably) have your custom down/up commands increment/decrement a value internally to your code on a timer, representing rudder position, then you can control the deflection per second or whatever, and also just pass that to DCS with iCommandPlaneRudder, instead of passing along iCommandPlaneLeftRudderStart/iCommandPlaneRightRudderStop etc. Hope you understand what I'm saying. Basically, change the input commands so that they don't affect SFM automatically, then feed the SFM the commands it needs (filtered/scaled/changed as desired) to move the rudder. You _might_ need to also then animate the rudder anim arg yourself, I'm not sure... but I think doing the dispatch will get the SFM to animate it for you, unless you're using a non-standard anim arg for the rudder (in which case you'd need to animate it yourself anyway with set_aircraft_draw_argument_value). If you plan on implementing any kind of electrical and hydraulic systems, you'll want to eventually "disconnect" the DCS inputs from the SFM anyway, so that you can insert your electrical/hydraulic/damage logic inbetween. For your specific case, it sounds like you'll want to scale the rudder input value based on your NWS setting when you have weight on wheels (e.g. get_base_data().getWOW_NoseLandingGear() ), and when you have no weight on wheels you want to pass along an unchanged rudder input value.
  2. If you're using SFM, then I think setting the rudder in effect performs nose wheel steering while on the ground.
  3. Yup, but it would be nice if ED or somebody else made an open-source SFM-level EFM example. Maybe someday I'll do it myself, I'd be very keen to do that. We're using a bunch of extended SFM tables for A-4E currently, there might be more that we don't know about. Basically: SFM_Data = { aerodynamics = { -- bunch of constants and tables we populate }, engine = { -- bunch of constants we populate here extended = { -- and a bunch of detailed sub tables in here that we populate } } } The SFM is really quite detailed, so it would be amazing if we could get an opensource SFM-level EFM. Some people think the SFM is just totally simple scripted behaviour, but it's not, it's a proper flight model (internal implementation in DCS, hidden from us), taking MANY parameters as inputs from the Lua. I think it's actually quite impressive for what it is. It is still much simpler than the PFM/AFM etc. flight models that the ED and 3rd party modules implement though, of course.
  4. If you haven't already, take a look at API/ExternalFMTemplate/ED_FM_Template in the DCS directory. There is a .sln file there that you can use to compile the whole thing in visual studio, and you can then use that dll as a flight model for your plane (make sure to select 64bit and release mode, else it doesn't work). It doesn't do much though, just a minimal example, but shows you exactly what the API looks like for implementing an EFM. The rest is up to you, lots of aeronautical and physics math equations etc., and coming up with an accurate model for your plane under all circumstances (attitudes, thrust conditions, control surface positions, damage etc.etc.). Not trivial.
  5. I have used this tool (thanks uboats!) a lot too, and it is useful, but it is orthogonal to what I wrote above. When you have your own cockpit and plane EDM, you don't need this tool as much anymore, since you can then keep internal documentation of what each arg is for (and the ranges etc.). It is very handy for poking at other EDM files though to get an idea of how they do things.
  6. True, but that is pretty much the Lua claim to fame and why it is used in virtually every game engine for scripting.
  7. A combination of recursively dumping metatable from _G to discover available function names, and trial&error&guesswork for the function parameters. In this particular case, I discovered the get_clickable_element_reference function directly in the _G metatable, then had to guess its param, which I finally got as the point name which the element was defined with, then I had to dump the metatable of the result of that to see that it had the set_hint, update and hide functions, and then had to guess their parameters. So it goes with DCS modding when you have no access to documentation, and when google doesn't give you a link to a forum post with the answer on it.
  8. Is there an example somewhere of how to make a minimal DLL with a C function that can be called from Lua (in avLuaDevice) in a DCS module cockpit? I've read a variety of posts, e.g. https://forums.eagle.ru/showthread.php?t=90368 https://forums.eagle.ru/showthread.php?p=1474382 and various Lua docs. I can load a DLL from a Lua file and call the C function, however I can't seem to make this work within a DCS aircraft mod. I add the DLL to the binaries list inside declare_plugin: binaries = { 'hellolib', }, but it's not clear to me whether this is even trying to load my DLL. I'm also not sure whether explicitly using require or loadlib is needed from the Lua code to open the DLL, since it seems to me that have the entry in the binaries list should cause DCS to open the DLL and make it accessible, besides which I haven't had any success using require or loadlib directly inside DCS Lua files anyway (works fine on standalone Lua files outside of DCS). I've created a DLL (64bit, Lua 5.1 headers etc.) with just the following cpp file, compiled to hellolib.dll: #include "stdafx.h" #include <windows.h> #include <stdio.h> #ifdef __cplusplus extern "C" { #endif // __cplusplus #include "lua.h" // the includes for the 64 bit LUA libray #include "lualib.h" #include "luaconf.h" #include "lauxlib.h" #ifdef __cplusplus } #endif // __cplusplus #define DllExport __declspec( dllexport ) static int l_hello(lua_State *L) { lua_pushnumber(L, 42); /* push result */ return 1; /* number of results */ } static const luaL_Reg Map[] = { {"hello", l_hello }, {NULL, NULL} }; DllExport int luaopen_hellolib( lua_State *L) { luaL_register(L, "MyGlobal", Map); // register the list of function return 1; } Then I place hellolib.dll inside the bin subdirectory of my mod, and add an entry to the binaries list in declare_plugin. None of that results in any errors in DCS.log, so either it is getting ignored or loaded successfully or failing silently. Then, where I want to try to call it inside an avLuaDevice instance, I've tried various things (one at a time) which all failed: r=hello() r=MyGlobal.hello() r=MyGlobal:hello() mylib=require("hellolib") -- tried various paths etc. here too to try to get it to load, to no avail -- mylib=require(current_mod_path.."/bin/hellolib") r=mylib:hello() Any ideas? As a bonus, it would be nice if the DLL could actually also access the APIs defined in the API\include\Cockpit\ccParametersAPI.h file, to be able to exchange param values with the Lua devices. I've been headbutting against this for several hours now, and I don't know whether I have few or many things wrong. Would really appreciate any tips from people that have successfully done this. ( Note: I am not talking about EFM dll here, I can get the ED_FM_Template dll compiled and working with our mod )
  9. Something that would provide a great leap forward for the DCS airplane mod community would be if somebody makes an opensource EFM with similar capabilities to the built-in SFM, which people can then extend/change as necessary for new aircraft mods. Ideally ED themselves would make this available as an enhancement/replacement to API/ExternalFMTemplate/ED_FM_Template.cpp (which is too simplistic to be of much use, other than being a minimal compilable EFM dll example). As heavily criticized as the SFM is, it still models a lot of stuff, and even trying to get that level of modelling done from scratch in an EFM would take a lot of work. Most 3rd party modules would still probably opt to completely replace such an example EFM, but it would at least give a head start to new mods (standing on the shoulders of giants etc.). I know there are some opensource EFM examples like the F-16 demo (originated by CptSmiley (I think) with various forks, the most up to date one being https://github.com/ipr/F-16Demo/ (I think) ), but I don't think it is generic enough for this purpose.
  10. Clickable buttons are definitely possible with Lua only, with no dll at all. We have many custom controls in our A-4E mod, both for keyboard/joystick bindings as well as clickable (animated) cockpit buttons/dials/levers etc. If you are still stuck, I can try to post some minimal distilled example code of what is needed. It is not difficult, but does require a few things to all be correct for it to work.
  11. Posting this to people of the future because google currently has zero results for "get_clickable_element_reference", and I figured out how to use it. Hopefully soon this post will become the only google hit for this. You can call get_clickable_element_reference("POINT_NAME"), where "POINT_NAME" comes from one of your items in your clickabledata.lua (index of the elements). On the result of that, you can then call the following functions: set_hint update hide set_hint updates the mouseover text of the clickable element dynamically (pass a string as an argument), hide takes a boolean as argument and changes whether the element is clickable or not (useful if you want elements to not be clickable under certain logic conditions), and update (takes no arguments) is useful to get a clickable element to update its connector position (this is useful if you have changed the cockpit draw argument of a clickable item (e.g. via a parameter gauge) instead of using the clickable animations (which are sometimes problematic since they only emit the command after the animation has completed, and you might want to employ some logic as soon as it is clicked before it starts animating) ). Example (emulating a gear lever which is locked by solenoid when on the ground, so make it non-clickable): if prev_retraction_release_airborne ~= retraction_release_airborne then local gear_clickable_ref = get_clickable_element_reference("PNT_8") -- gear lever prev_retraction_release_airborne = retraction_release_airborne gear_clickable_ref:hide(not retraction_release_airborne) -- make non-clickable if not airborne, and clickable when airborne end
  12. Just duplicating what I said on discord on 2016-11-23: If I dump the functions from get_base_data in DCS, I get the following: getAngleOfAttack getAngleOfSlide getBarometricAltitude getCanopyPos getCanopyState getEngineLeftFuelConsumption getEngineLeftRPM getEngineLeftTemperatureBeforeTurbine getEngineRightFuelConsumption getEngineRightRPM getEngineRightTemperatureBeforeTurbine getFlapsPos getFlapsRetracted getHeading getHelicopterCollective getHelicopterCorrection getHorizontalAcceleration getIndicatedAirSpeed getLandingGearHandlePos getLateralAcceleration getLeftMainLandingGearDown getLeftMainLandingGearUp getMachNumber getMagneticHeading getNoseLandingGearDown getNoseLandingGearUp getPitch getRadarAltitude getRateOfPitch getRateOfRoll getRateOfYaw getRightMainLandingGearDown getRightMainLandingGearUp getRoll getRudderPosition getSelfAirspeed getSelfCoordinates getSelfVelocity getSpeedBrakePos getStickPitchPosition getStickRollPosition getThrottleLeftPosition getThrottleRightPosition getTotalFuelWeight getTrueAirSpeed getVerticalAcceleration getVerticalVelocity getWOW_LeftMainLandingGear getWOW_NoseLandingGear getWOW_RightMainLandingGear I think the only new ones compared to the list you gave are: getSelfAirspeed getSelfCoordinates getSelfVelocity
  13. get_cockpit_draw_argument_value works fine for me (at least inside an avLuaDevice instance), I use it to do exactly what you describe above (update another draw argument based on the position of a cockpit draw argument). AFAICT, these are all valid functions: get_aircraft_draw_argument_value set_aircraft_draw_argument_value get_cockpit_draw_argument_value Note that there is no set_cockpit_draw_argument_value, AFAIK you can only set them indirectly via parameter gauges.
  14. The SFM sortof forces nosewheel steering on us, but I have a workaround in mind that I'm reasonably sure would do a fair job of approximating differential braking instead of nosewheel steering (similar trick that I used to implement the spoilers, which SFM doesn't model). However, it is so far down my priority list that I had completely forgotten about it until you mentioned it now. It is still pretty far down on my priority list though :) It will take a few hours to implement, and at the end of it the idea might not work at all (or not work adequately), so I'm a bit hesitant to take it on. IIRC, the A-4F did have nosewheel steering, so for now we can just pretend that our very late A-4E had the nosewheel steering upgrade backported to it. The SFM places a bunch of restrictions on us, but the flip side is that if we want to contemplate EFM, it would be a massive amount of additional work.
  15. I looked into this a little bit, and got the C++ template sample (in DCS subdirectory) compiled to a dll and running with our A-4E. However, even making an EFM do "only" what the SFM does would already be a LOT of work, the SFM is not quite as simple as some people seem to think. Then going above and beyond the SFM to try to more realistically model the A-4E would be even more work of course, and possibly require access to more A-4E data than we have or even maybe wind tunnel tests with a scale model etc. I can't really see us tackling this on a part time basis and completing it within any reasonable timeframe, and none of us is (AFAIK) financially independent enough to work full time on this without pay for any extended period of time.
  16. Some parts of wHumanCustomPhysicsAPI.h maybe give some tiny clues/insight: // damages and failures // void ed_fm_on_planned_failure(const char * ) callback when preplaneed failure triggered from mission typedef void (*PFN_ON_PLANNED_FAILURE) (const char *); If we can get the corresponding Lua callback, then we could get the mission editor failures too. Basically just a callback with a string value (from the Failures entry in the aircraft definition) which the code must interpret as it wants to. // void ed_fm_on_damage(int Element, double element_integrity_factor) callback when damage occurs for airframe element typedef void (*PFN_ON_DAMAGE) (int Element, double element_integrity_factor); I initially thought (see my first post above) that SetDamage in the Lua is maybe a callback similar to SetCommand.. it may well still be (like ed_fm_on_damage callback), but perhaps needs to be registered somehow (similar to how one needs to do listen_command prior to getting SetCommand callbacks). //inform DCS about internal simulation event, like structure damage , failure , or effect struct ed_fm_simulation_event { unsigned event_type; char event_message[512]; // optional float event_params [16]; // type specific data , like coordinates , scales etc }; // bool ed_fm_pop_simulation_event(ed_fm_simulation_event & out) called on each sim step /* ed_fm_simulation_event event; while (ed_fm_pop_simulation_event(event)) { do some with event data; } */ typedef bool (*PFN_FM_POP_SIMULATION_EVENT) (ed_fm_simulation_event & out); // event type declaration enum ed_fm_simulation_event_type { ED_FM_EVENT_INVALID = 0, ED_FM_EVENT_FAILURE, ED_FM_EVENT_STRUCTURE_DAMAGE, ED_FM_EVENT_FIRE, }; /* ED_FM_EVENT_FAILURE event_message - failure id , like "autopilot" or "r-engine" event_params - not used for failure ED_FM_EVENT_STRUCTURE_DAMAGE event_message - not used event_params[0] damage element number like in ed_fm_on_damage event_params[1] integrity factor like in ed_fm_on_damage ED_FM_EVENT_FIRE event_message - not used , but you can send something like "engine fire" or "left wing tank fire" event_params[0] fire control handle, index used to control change of effect in time event_params[1] event_params[2] event_params[3] x , y ,z coordinates of fire origin in aircraft body space event_params[4] event_params[5] event_params[6] x , y ,z components of orientation of emitter direction event_params[7] emitted particles speed event_params[8] scale of fire , if scale will less or equal to zero , fire with this index will be stopped */ There seems to be a listen_event Lua function, which maybe works similar to the listen_command function used for getting all clickable cockpit commands... Perhaps one can then somehow receive events similar to the C API above.
  17. Yeah, sometimes it takes some fiddling with settings to get IR LEDs and modified PS3 Eye and Opentrack all "in balance". In my case I had to use the CL-Eye program to set the camera settings to make gain 0 (all the way to the left) and exposure very nearly zero and disable all the "auto" checkboxes. That way (assuming the IR filter was removed from your PS3 Eye) it picks up the bright IR LEDs as quite small spots and everything else is close to black. Then in opentrack you need to fiddle with the threshold and min/max size settings in the pointtracker, and ensure FOV matches the setting on your camera (mine is on red dot, so 56º, see PS3 Eye). This is why I still want to get one of those narrowband IR passthrough filters I mentioned in my previous post, that will cut down significantly on any other inputs that don't have the wavelength of your IR LEDs. In my case, the IR-333 LEDs I used have a wavelength of 940nm, so I'd need to get this filter. So yes, like I said, it does take a lot of tweaking to get everything working nicely, if you don't have the time or appetite for that, just shell out $150 for TrackIR5 and be done with it. In my country the TrackIR5 is more like $200 or $250 after shipping and import tax, so sub $20 to make my own setup seemed worthwhile at the outset (I'm not so sure afterwards anymore though, it took way more effort and time than I thought it would...but it works really well now, so now I have no more reason to get a TrackIR5).
  18. I used facetracking for a while (both with Facetrack_NoIR and with the facetrack plugin in opentrack (which has since been removed) ), but it always seems to "drift" over an hour of gaming, and sometimes just went crazy, or had a constant "vibration". I eventually just bit the bullet, and built a 3 point IR LED module on an old headlamp (I dubbed it the Antl-IRs), and then later made a proper cap (the headlamp was too uncomfortable). Together with OpenTrack and a modified PS3 Eye camera, this works amazingly well and very stable, EXCEPT under certain lighting conditions certain times of the day (e.g. lots of early morning bright sunshine reflecting off my face or behind me etc.). I think I can probably solve those issues with some filters (e.g. these ), but it hasn't really been a priority yet (I don't generally game at the time of day when the problem is present). Making a hat like this is not difficult, but it can take quite a while (and mine is not even pretty, making it look nice (hiding wiring etc.) would take even more time), I would recommend to just order one off trackhat.org (e.g. this) or one of those sites, even with international shipping it should still be quite reasonable, maybe $100 total. You can make the hat for under $20 (including the cost of a PS3 Eye camera), so basically depends how much a few hours of your time is worth to you. The trackhat one even has a forked version of opentrack with a simplified UI catering for trackhat dimensions to make it even easier to get going (with normal opentrack you'll need to spend some more time getting everything configured nicely). From what I've seen, a well configured opentrack with PS3 Eye and a hat can rival a TrackIR5 setup, BUT the large benefit of TrackIR5 is that it largely "just works", no mucking about with configs and camera settings to get things working etc. For $150 that might even be reasonable, especially if trackhat kit with shipping is close to $100.
  19. I made a short video to demonstrate one of the features we implemented back in August: You can see the gunsight reflector glass animating when the knob is turned, and the projected gunsight still maintains correct clipping at high and low angles of the glass. Now that we're starting to calibrate the sights for the weapon releases (gunsight mil angles for combinations of airspeed, weapon, dive angle and altitude), we've run into a problem, so ultimately we may be forced to abandon this animated reflector glass. I thought it was cool enough to show it in action here, hoping we can find a way to solve the issue and keep it in.
  20. I forgot to follow up on the above, so for posterity: It is indeed possible to use change_color_when_parameter_equal_to_number several times, with a unique matching value for each colour triplet, e.g. {"change_color_when_parameter_equal_to_number", 1, 1, 1.0,0.5,0.0}, {"change_color_when_parameter_equal_to_number", 1, 0.9, 0.9,0.45,0.0}, {"change_color_when_parameter_equal_to_number", 1, 0.8, 0.8,0.40,0.0}, {"change_color_when_parameter_equal_to_number", 1, 0.7, 0.7,0.35,0.0}, then setting FOO_PARAM2 to 0.7 will set your element colour to 0.7,0.35,0.0 for instance. If all you really need is to change the brightness of something, then opacity_using_parameter works better, and simply setting it to some value between 0 (invisible) and 1 (fully opaque).
  21. You can maybe try line_object_set_point_using_parameters, but I have no idea how it works, never tried it before.
  22. I'm hoping somebody here can point me in the right direction. I want to be able to detect damage to various parts of an SFM/SSM aircraft in Lua. The main aircraft definition file has entries such as: --damage , index meaning see in Scripts\Aircrafts\_Common\Damage.lua Damage = { [0] = {critical_damage = 5, args = {82}}, -- 0 - nose center [3] = {critical_damage = 10, args = {65}}, -- 3 - cockpit and DamageParts = { [1] = "plane_damage_wing_R", -- Right Wing [2] = "plane_damage_wing_L", -- Left Wing and Failures = { { id = 'autopilot', label = _('AUTOPILOT'), enable = false, hh = 0, mm = 0, mmint = 1, prob = 100 }, { id = 'engine', label = _('ENGINE'), enable = false, hh = 0, mm = 0, mmint = 1, prob = 100 }, Damage and DamageParts seem to define the anim args and 3D models that are activated on various system damage (I've also trawled the Scripts\Aircrafts\_Common\Damage.lua file for further clues with no success). Failures seems to show up in mission editor and flight logs in game (though I don't know how to make those failures associated with any code either). All the aircraft systems are implemented as simple avLuaDevice entries, e.g. creators = {} creators[devices.AVIONICS] = {"avLuaDevice", LockOn_Options.script_path.."Systems/avionics.lua"} creators[devices.RADARWARN] = {"avLuaDevice", LockOn_Options.script_path.."Systems/radarwarn.lua"} creators[devices.ENGINE] = {"avLuaDevice", LockOn_Options.script_path.."Systems/engine.lua"} creators[devices.GUNSIGHT] = {"avLuaDevice", LockOn_Options.script_path.."Systems/gunsight.lua"} My question is: how can I detect/query damage (or failures) to parts of the aircraft from within those avLuaDevice systems Lua code? I've noticed (from checking key/value pairs of the avLuaDevice object, and looking at DCS dll files) that there is a function named SetDamage, but I'm unsure whether it is a callback (like SetCommand and update) or whether an API meant to be called by our code. I've tried just implementing a SetDamage function with a print_message_to_user, but it never gets triggered (even when the aircraft is just a flying ball of fire after being shot to bits), so it doesn't seem to be a callback (unless something more needs to be done to register the system somehow). If I can detect or query damage to specific parts of the plane somehow, I can start to emulate damage to the various systems in the code, e.g. have some electrical or hydraulics failures, radar altimeter failures, etc. etc. Any pointers in the right direction would be greatly appreciated!
  23. With regard to finding animation argument numbers for plane and cockpit models, this is VERY handy: http://www.digitalcombatsimulator.com/en/files/1797654/
  24. OK, I figured out one of them: foo.element_params = {"FOO_PARAM", "FOO_PARAM2"} foo.controllers = { {"move_up_down_using_parameter", 0, 0.1 }, {"change_color_when_parameter_equal_to_number", 1, 1, 0.0,1.0,0.0}, Setting FOO_PARAM2 to 1 changes the colour of the element to green (RGB given by 0.0,1.0,0.0), and setting FOO_PARAM2 back to something else causes it to revert to original colour. Haven't tried yet, but I'm guessing one can either add more args for more value/colour combinations, or use change_color_when_parameter_equal_to_number multiple times.
  25. I've successfully used some of the HUD element controllers, e.g. foo.element_params = {"FOO_PARAM"} foo.controllers = { {"move_up_down_using_parameter", 0, 0.1 }, } The ones that I currently use are: move_left_right_using_parameter, move_up_down_using_parameter, parameter_in_range, text_using_parameter, opacity_using_parameter The first arg in each controllers entry is the function name (e.g. move_up_down_using_parameter), the second arg is the (0-based) index into the element_params array to determine the param name, and the 3rd arg (and perhaps optional additional args after that?) is used with the function in question (e.g. the 0.1 above scales how much the element moves up and down with the changing value of FOO_PARAM). I found a few others in Cockpitbase.dll that sound useful, but I don't know how to use some of them (others I can guess): change_texture_state_using_parameter, change_color_when_parameter_equal_to_number Anybody have more info on these?
×
×
  • Create New...