Orbiter-Forum  

Go Back   Orbiter-Forum > Orbiter Addons > Orbiter Lua Scripting
Register Blogs Orbinauts List Social Groups FAQ Projects Mark Forums Read

Orbiter Lua Scripting Find support, share snippets and general discussion around using the Lua engine in Orbiter.

Reply
 
Thread Tools
Old 10-17-2017, 09:18 PM   #1
kuddel
Donator
Default Orbiter BETA Lua development

Finally here's the Lua (sub-)Forum!

My current progress and questions regarding the Orbiter Lua API will be posted here.

I will update this 1st post with the current state, as soon as it changed.
New items (since last edit of this post) will be marked green

The attached file represents the current "work in progress" and might still contain some "todo"s.
The attached ZIP contains only files with changes to keep the ZIP-size small.

Almost all the added functions in the current ZIP (2017-12-08) have documentation.
Some of the documentation might not fit the 'ldoc-rules', 'cause I haven't installed ldoc.
The latest update (LuaScript 2017-12-08.zip) only contained documentation changes, therefore no new DLL package was uploaded

For the time being, here are some documentation snippets/hints/details here.

Current status:

Terminal:
- term.clear()

OAPI:
- oapi_get_orbiter_version()
- oapi_get_viewport_size()
- oapi_rand()
- oapi_getcolor()
- oapi.get_annotations()

Vessel-API:
- get_COG_elev()
- get_touchdownpointcount()
- get_touchdownpoints()
- set_touchdownpoints()
- get_clipradius()
- set_albedoRGB()
- set_clipradius()
- set_surfacefrictioncoeff()
- get_status()
- defset_status()
- get_angularacc()
- get_linearmoment()
- get_angularmoment()
- get_globalorientation()
- set_globalorientation()
- is_orbitstabilised()
- is_nonsphericalgravityenabled()
- get_surfaceelevation()
- get_surfacenormal()
- get_smi()
- get_argper()
- get_pedist()
- get_apdist()
- toggle_navmode()
- toggle_rcsmode()
- get_hoverholdaltitude()
- set_hoverholdaltitude()
- version()
- get_dragvector()
- get_forcevector()
- get_torquevector()
- add_force()
- edit_airfoil()
- dockingstatus()
- get_animation()
- del_animationcomponent()
- register_animation()
- unregister_animation()
- set_cameradefaultdirection()
- get_cameradefaultdirection()
- set_cameracatchangle()
- set_camerarotationrange()
- set_camerashiftrange()
- set_cameramovement()[/COLOR]
// coordinate transformations
- shift_centreofmass()
- shiftCG()
- get_superstructureCG()
- get_rotationmatrix()
- set_rotationmatrix()
- globalrot()
- horizonrot()
- horizoninvrot()
- local2global()
- global2local()
- local2rel()
- set_thrusterlevel_singlestep()
// Nosewheel-steering and wheel brakes
- set_nosewheelsteering()
- get_nosewheelsteering()
- set_maxwheelbrakeforce()
- set_wheelbrakelevel()
- get_wheelbrakelevel()
// Instrument panel and virtual cockpit methods
- trigger_panelredrawarea()
- trigger_redrawarea()


Documentation details:

term.clear() :
This method clears the terminal window.

get_touchdownpoints :
This method uses a polymorphic approach.
If the function is called without any parameter, it will return three vectors representing the three touchdownpoints as per the "old" API.
If hte function is called with an index as parameter, it will return the "new" TOUCHDOWNVTX table.
The TOUCHDOWNVTX table contains the following key value pairs:
- "pos" (vector)
- "stiffness" (number)
- "damping" (number)
- "mu" (number)
- "mu_lng" (number)

set_touchdownpoints :
This method uses a polymorphic approach.
If the function is called with three vectors, it will perform the "old" API action.
If the function is called with one list (table) containing at least 3 TOUCHDOWNVTX tables, it will perform the "new" API action.

Example:
Code:
v = vessel.get_focusinterface()

// ----------------------------------------------------------------
p1,p2,p3 = v:get_touchdownpoints()  // OLD, 'cause no index provided
v:set_touchdownpoints(p1, p2, p3)   // OLD, 'cause three vectors provided

// ----------------------------------------------------------------
arr = {}
arr[1] = v:get_touchdownpoints(0) // NEW, 'cause index provided
arr[2] = v:get_touchdownpoints(1) // NEW,   "     "     "
arr[3] = v:get_touchdownpoints(2) // NEW,   "     "     "
v:set_touchdownpoints(arr)        // NEW, 'cause table with at least 3 TOUCHDOWNVTX tables given
get_status :
This method can be used to get either the "version 1" VESSELSTATUS or the "version 2" VESSELSTATUS2 table.
The first parameter can be used to distinguish between these two:
- 1: Return "version 1" table
- 2: Return "version 2" table (default if no parameter is given)

The VESSELSTATUS2 table contains the following key value pairs:
- "version" (number) // always 2
- "flag" (number)
- "rbody" (OBJHANDLE)
- "base" (OBJHANDLE)
- "port" (number)
- "status" (number)
- "rpos" (vector)
- "rvel" (vector)
- "vrot" (vector)
- "arot" (vector)
- "surf_lng" (number)
- "surf_lat" (number)
- "surf_hdg" (number)
- "fuel" (list of tables) each containing a "idx" (number) and a "level" (number) member
- "thruster" (list of tables) each containing a "idx" (number) and a "level"(number) member
- "dockinfo" (list of tables) each containing a "idx" (number), "ridx" (number) and a "rvessel" (OBJHANDLE) member
- "xpdr" (number)

The VESSELSTATUS table contains the following key value pairs:
- "rpos" (vector)
- "rvel" (vector)
- "vrot" (vector)
- "arot" (vector)
- "fuel" (number)
- "eng_main" (number)
- "eng_hovr" (number)
- "rbody" (OBJHANDLE)
- "base" (OBJHANDLE)
- "port" (number)
- "status" (number)
- "vdata" (vector) // ignored [1]...[9]
- "fdata" number) // "
- "flag" (number) // "

Example:
Code:
v = vessel.get_focusinterface()
v:get_status()  // returns VESSELSTATUS2 table
v:get_status(1) // returns VESSELSTATUS table
v:get_status(2) // returns VESSELSTATUS2 table
defset_status :
This method can be used to set either a "version 1" VESSELSTATUS or a "version 2" VESSELSTATUS2 table.
The method distinguishes the type just by checking if the value of the ["version"] field in the given table equals 1 or 2.
This method only changes the values that are given in the table, any not mentioned values will not be changed!
Any "unknown" fields will be ignored.

Example:
Code:
v = vessel.get_focusinterface()
vect = { x=1, y=2, z=3 }

v:defset_status("dummy") // <= results in error
v:defset_status({}) // <= results in error (no ["version"] specified)
v:defset_status({ version=2 }) // <= OK, but does not change anything
v:defset_status({ version=1 }) // <= same as above (with "old" VESSELSTATUS)
v:defset_status({ version=2, port=666 }) // <= will only change the port
v:defset_status({ version=2, port=666, foo="bar" }) // <= same as above, all unknown fields will be ignored
v:defset_status({ port=666, arot=vect, version=2 }) // <= OK as long as vect is a VECTOR; the order of the fields is irrelevant
oapi.deflate :
This function deflates (or packs) a string.
This function is called with one string (a bytes array, as Lua strings can contain binary zero as well)

oapi.inflate :
This methods inflates (or unpacks) a packed string that was packed by oapi.deflate() or by the according Orbiter core function.
The new tree-data files for example are packed this way.
This function is called with one string (a bytes array, as Lua strings can contain binary zero as well)

Example:
Code:
local inp = "Hello World!\nHello World!\nHello World!\nHello World!" -- input buffer
local pak = oapi.deflate(inp)
local out = oapi.inflate(pak)

term.out(#inp .. ' => ' .. #pak .. ' => ' .. #out)
term.out("Result: " .. tostring(inp == out))
oapi.get_annotations :
This method returns a list of all currently created annotation handle objects.
This was added mainly as an option while debugging, as newly created annotation handle objects are not automatically deleted when running a script via the "run()" command. So each time a script was run ("run 'script'" rsp. "run('script')") the previous annotatos were not cleared.
Here's an example how this method can be used:
Code:
-- re-use 1st 'old' annotation object (if available)
local noteTop = oapi.get_annotations() or oapi.create_annotation()
This is functionally equal to the following code:
Code:
local noteTop = oapi.get_annotations()
if noteTop == nil then
  noteTop = oapi.create_annotation()
end
...just written a bit more 'cool'

Another way of usage (to clear all 'old' annotation objects) would be:
Code:
-- delete any 'old' annotation objects
for key,value in pairs({oapi.get_annotations()}) do
  oapi.del_annotation(value)
end

Note: Current implementation in Orbiter BETA cannot print (via term.out) some of the "more complex" structures, so you might have to explicitly access sub-members like "term.out(vesselstat2.fuel[1])" or "term.out( #vesselstat2.thruster )"
Attached Files
File Type: zip LuaScript 2017-12-07(dlls).zip (104.7 KB, 10 views)
File Type: zip LuaScript 2017-12-08.zip (85.9 KB, 11 views)

Last edited by kuddel; 12-08-2017 at 07:55 PM.
kuddel is offline   Reply With Quote
Old 10-18-2017, 11:41 AM   #2
martins
Orbiter Founder
Default

Cool, we've got a Lua forum now - thanks Josh for setting this up!

Just a quick aside - it's actually "Lua" ("Moon"), not "LUA". It's pedantic I know, but the authors are adamant about it, so we might as well stick to it.

Quote:
Originally Posted by kuddel View Post
 Due to the fact that Martin has to write the documentation, I might add documentation snippets/hints/details here, too.
Oops, I hadn't realised that I still have to do the documentation. Would it help if I provided the html docs for the Lua part of the orbiter.chm file? Unfortunately the entire Lua interface documentation is done manually. I haven't found a way to get doxygen to document the API interface functions. If anybody can come up with a more efficient way please let me know.

In fact, if the Lua interface development is becoming a community effort, maybe we should think about using github or similar.

Another point: the current Lua terminal isn't very well written. I was wondering if there is any code for a generic terminal implementation available that we could use. Something that has basic functionality (input line editing, copy/paste, history, maybe even syntax highlighting and command completion).
martins is offline   Reply With Quote
Thanked by:
Old 10-18-2017, 01:17 PM   #3
4throck
Enthusiast !
 
4throck's Avatar
Default

I'm using Notepad ++ for Lua editing.
There's a syntax checker but of course it ignores all Orbiter functions.

One possibility would be to add the extra Orbiter syntax and commands, I think it's possible.
Does anyone have any experience with this?
4throck is offline   Reply With Quote
Old 10-18-2017, 01:30 PM   #4
Xyon
Puts the Fun in Dysfunctional
 
Xyon's Avatar


Default

Quote:
Originally Posted by martins View Post
 Another point: the current Lua terminal isn't very well written. I was wondering if there is any code for a generic terminal implementation available that we could use. Something that has basic functionality (input line editing, copy/paste, history, maybe even syntax highlighting and command completion).
If it could be embedded in somehow, perhaps something like luaprompt could work? It says it's provided as a Lua rock, which pleases me greatly for the lexical comedy while at the same time meaning nothing to me on a package management level.
Xyon is offline   Reply With Quote
Thanked by:
Old 10-18-2017, 01:34 PM   #5
Urwumpe
Certain Super User
 
Urwumpe's Avatar

Default

Quote:
Originally Posted by 4throck View Post
 I'm using Notepad ++ for Lua editing.
There's a syntax checker but of course it ignores all Orbiter functions.

One possibility would be to add the extra Orbiter syntax and commands, I think it's possible.
Does anyone have any experience with this?
I implemented a Javascript editor in a Java application once with Syntax highlighting and auto-complete for the external API of the application. But I think, for Orbiter, should look at other alternatives first. It was very little code, but very Java specific and was configured by annotations in the script engine binding.

Maybe something like that could be a choice?

https://marketplace.visualstudio.com...xnz.vscode-lua
Urwumpe is online now   Reply With Quote
Thanked by:
Old 10-18-2017, 03:26 PM   #6
martins
Orbiter Founder
Default

Those look interesting - I'll have a look.

Quote:
Originally Posted by Xyon View Post
 If it could be embedded in somehow, perhaps something like luaprompt could work? It says it's provided as a Lua rock, which pleases me greatly for the lexical comedy while at the same time meaning nothing to me on a package management level.
Quote:
Originally Posted by Urwumpe View Post
 Maybe something like that could be a choice?

https://marketplace.visualstudio.com...xnz.vscode-lua
One more important feature I forgot to mention is support for entering commands spanning multiple lines, so that not every command has to be entered on a single line. Without it, complex commands like loops are nearly impossible to enter in the terminal. Since both your suggestions are Lua-specific, I guess they should support this.
martins is offline   Reply With Quote
Thanked by:
Old 10-18-2017, 05:18 PM   #7
Urwumpe
Certain Super User
 
Urwumpe's Avatar

Default

Well, my solution wouldn't work as suitable embedded script terminal, its just a very good code editor.

Wouldn't it be possible in theory to create such a terminal window as plain add-on and have the choice to select which one suits somebody more?
Urwumpe is online now   Reply With Quote
Old 10-18-2017, 05:24 PM   #8
martins
Orbiter Founder
Default

Quote:
Originally Posted by Urwumpe View Post
 Wouldn't it be possible in theory to create such a terminal window as plain add-on and have the choice to select which one suits somebody more?
Yes, certainly. It's already an addon (Orbitersdk/samples/LuaScript/LuaConsole), but AFAIK nobody has written a replacement so far, so I thought I'd bring it up.
martins is offline   Reply With Quote
Thanked by:
Old 10-18-2017, 06:57 PM   #9
kuddel
Donator
Default

Quote:
Originally Posted by martins View Post
 Would it help if I provided the html docs for the Lua part of the orbiter.chm file?
Noooo, that would mean I would feel guilty when I didn't edit those, too
Now really: Adding those files to the repository would not only make it possible to add the documentation for each new function directly, it would also make the Solution & Project-files valid

I don't know whether the generator that converts the ".htm" files into the orbiter.chm file would make it into the repository (the Orbiter documentation sources will/should still remain closed-source).
But being able to add/edit the Lua documentation directly would be better. Even if the "compilation" into Orbiter.chm has still to be done by you Martin.
Possible "syntax errors" in those .htm files would have to be fixed by you then.


Quote:
Originally Posted by martins View Post
 Another point: the current Lua terminal isn't very well written. I was wondering if there is any code for a generic terminal implementation available that we could use. Something that has basic functionality (input line editing, copy/paste, history, maybe even syntax highlighting and command completion).
Yes, but that could be developed completely independent.
Regarding the "multiple lines" : I think the terminal is just a terminal, not an editor. Usually you don't write complex scripts in a terminal, you open VI or emacs for that

Last edited by kuddel; 10-18-2017 at 07:05 PM.
kuddel is offline   Reply With Quote
Old 10-18-2017, 09:04 PM   #10
Xyon
Puts the Fun in Dysfunctional
 
Xyon's Avatar


Default

If you've ever developed in python, think about the utility of ipython - interpreter within the terminal, good syntax support and modular autocompletion
Xyon is offline   Reply With Quote
Old 10-18-2017, 10:07 PM   #11
kuddel
Donator
Default

I've uploaded my current state of work and updated the 1st post accordingly.

BTW: luaprompt looks interesting.
O.K. now I wonder who's gonna be the first to port it for Orbiters LuaConsole
...ready,...steady,...

Last edited by kuddel; 10-18-2017 at 10:09 PM.
kuddel is offline   Reply With Quote
Thanked by:
Old 10-19-2017, 10:35 AM   #12
N_Molson
Addon Developer
 
N_Molson's Avatar

Default

Good stuff, please keep it on !
N_Molson is offline   Reply With Quote
Old 10-19-2017, 01:44 PM   #13
martins
Orbiter Founder
Default

Quote:
Originally Posted by kuddel View Post
 Regarding the "multiple lines" : I think the terminal is just a terminal, not an editor. Usually you don't write complex scripts in a terminal, you open VI or emacs for that
One situation where I can see this being useful is if you want to copy a portion of a script and drop it in the terminal window for debugging purposes.

Of course, even better would be an integrated debugger where you have the script and command prompt side by side. You place breakpoints in the script, and then use the command window to inspect or modify variables, etc. I doubt that something like this exists for Lua, and it would be too much effort to implement it just for Orbiter.
martins is offline   Reply With Quote
Thanked by:
Old 10-19-2017, 02:28 PM   #14
Urwumpe
Certain Super User
 
Urwumpe's Avatar

Default

I think a multi-line input isn't the big problem, you could for example also use a scratchpad approach there using something like "\" as indication that this line should be continued.

And maybe display continued lines in the output window first before committing them.

And yes, a full script editor window with breakpoint capability would be the best... but that's also the most complex to implement.

I think a simple terminal window with something like a "Orbiter Lua Shell" would already be good enough, in terms of UI.

For being really posh, there could also be oscilloscope-like view for plotting Lua variables over orbiter time next to it.
Urwumpe is online now   Reply With Quote
Thanked by:
Old 10-19-2017, 09:32 PM   #15
kuddel
Donator
Default

I have a Orbiter API question (to Martin):

The documentation of VESSEL::GetStatusEx (void *status) says:
Quote:
Note: In addition, the caller must set the VS_FUELLIST, VS_THRUSTLIST
and VS_DOCKINFOLIST bits in the flag field, if the corresponding
lists are required. Otherwise Orbiter will not produce these lists.
Note: If VS_FUELLIST is specified and the fuel field is NULL, Orbiter
will allocate memory for the list. The caller is responsible for
deleting the list after use
. If the fuel field is not NULL, Orbiter
assumes that a list of sufficient length to store all propellant
resources has been allocated by the caller.
Note: The same applies to the thruster and dockinfo lists.
I've tried to free the memory with
"if (status.fuel) delete[] status.fuel;"
and also tried
"if (status.fuel) free(status.fuel);"
, both giving me a heap corruption.

Can you shed some light into this?

---------- Post added at 23:32 ---------- Previous post was at 20:41 ----------

Phew! Implementing those tables and "lists" via the Lua stack operations is really a PITA
Nevertheless, some bugs fixed, some functions added and vessel get_status() and defset_status() completed.

Have fun,
Kuddel

Last edited by kuddel; 10-19-2017 at 10:14 PM.
kuddel is offline   Reply With Quote
Thanked by:
Reply

  Orbiter-Forum > Orbiter Addons > Orbiter Lua Scripting


Thread Tools

Posting Rules
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
Forum Jump


All times are GMT. The time now is 08:48 AM.

Quick Links Need Help?


About Us | Rules & Guidelines | TOS Policy | Privacy Policy

Orbiter-Forum is hosted at Orbithangar.com
Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Copyright 2007 - 2017, Orbiter-Forum.com. All rights reserved.