General Question How to display elapsed time on a script?

dgatsoulis

ele2png user
Donator
Joined
Dec 2, 2009
Messages
2,021
Reaction score
623
Points
128
Location
Sparta
Hi everyone.

I am making a script for a challenge and i want to be able to show on screen, how much time has passed since the engines of the spacecraft were ignited, in a similar way that you can see how much fuel you have spent, in the 2010 edition/Challenges scenarios.

Here is what i have so far:
Code:
-- read high score list from file
function hscore_read (file,n)
    local slist={}
    local f = io.open(file,"r")
    if f ~= nil then
        for i=1,n do
            local t = f:read()
            if t == nil then break end
            local name,time
            _,_,name,time = string.find (t, "(.-):(.+)")
            slist[i]={name,tonumber(time)}
        end
        f:close()
    end
    return slist
end

-- write high score list to file
function hscore_write (file,hscore)
    local f = io.open(file,"w")
    for i=1,#hscore do
        f:write(hscore[i][1]..':'..hscore[i][2]..'\n')
    end
    f:close()
end

-- convert high score list to a string
function hscore2str (hscore,mark)
    local str
    if #hscore > 0 then
        str = 'High score list:\n\n'..string.format('%s   %s', 'Time', 'Name')..'\n----------------------------------'
        for i=1,#hscore do
			str = str..'\n'..string.format('%08.2f    %s', hscore[i][2], hscore[i][1])
            if mark==i then str = str..'   <====' end
        end
    else
        str = 'No high scores yet!'
    end
    return str
end


data_path = 'Script/XR2 Challenges/Challenge5.dat' -- high score file
max_score = 10 -- max high score entries

intro = 'Flight challenge:\n\
Launch the XR2 Ravenstar into orbit and dock\
with the International Space Station\
as fast as you can.\
Time will begin counting when you ignite\
your engines. Good luck!\n'

note = oapi.create_annotation()
note:set_pos (0.3,0.05,0.9,0.95)
note:set_colour ({r=1,g=0.6,b=0.2})
note:set_text (intro) 

-- read highscore list
slist = hscore_read (data_path, max_score)


-- sanity checks
v = vessel.get_interface('XR2-01')
if v == nil then
    term.out ('Could not find XR2-01. Aborting')
    return
elseif v:get_classname() ~= 'XR2Ravenstar' then
    term.out ('Wrong vessel class. Aborting')
    return
end

hd = v:get_dockhandle (0)
hp0 = v:get_propellanthandle(0) -- main tank
hp1 = v:get_propellanthandle(1) -- RCS tank
m1 = v:get_propellantmass(hp0) + v:get_propellantmass(hp1)

-- wait for engines
while v:get_propellantmass (hp0) + v:get_propellantmass(hp1) == m1 do
    proc.skip()
end
t0 = oapi.get_simtime()

-- wait for docking event
mate = v:get_dockstatus (hd)
while mate==nil do
    proc.skip()
    mate = v:get_dockstatus (hd)
    if mate ~= nil then -- make sure we are docked to ISS
        v2 = vessel.get_interface(mate)
        if v2:get_name()~='ISS' then mate = nil end
    end
end
t1 = oapi.get_simtime() 

-- write out the results
dt = t1-t0
ptext = "Challenge completed successfully!\n"
ptext = ptext..string.format ("Mission Elapsed Time: %.2f seconds", dt)
note:set_pos (0.3,0.15,0.9,0.95)
note:set_size (1)
note:set_text (ptext)

-- enter high score list!
if #slist<max_score or dt < slist[#slist][2] then
	ptext = ptext.."\n\nYou made it into the high score!"
	note:set_text (ptext)
    name = proc.wait_input ('High score: Enter your name:')
    idx = #slist+1
    for i = 1,#slist do
        if slist[i][2] > dt then idx=i; break end
    end
    table.insert(slist,idx,{name,dt})
    if #slist > max_score then table.remove(slist) end
    hscore_write (data_path, slist)
end

ptext = ptext..'\n\n'..hscore2str(slist,idx)
note:set_text (ptext)
proc.wait_sysdt(30)
oapi.del_annotation (note)

I'm able to get the Mission Elapsed Time when i dock with the ISS, but am not so sure as to what i have to add, in order to get the MET while i'm flying.

Any help is much appreciated.
:cheers:
 
Last edited:
EDIT: corrected to get_mjd

Can't you just invoke oapi.get_mjd() and save the value when the engines start? (You could poll the engine thrust levels each second or so.) Then invoke oapi.get_mjd() later and get the delta (nowMJD - engineStartMJD).
 
Last edited:
That works right up until you restart the simulation and the clock resets, surely?
 
EDIT: good catch, mate: I should have said "MJD". :)

Well, he'd have to save the engine MJD at start in the scenario file on save and restore it on load if he wants it to work across restarts (no way around that). That's how the XRs handle MET - they save and load the wheels-up MJD. Same for the two interval timers -- they save and load the timer start MJD.
 
Last edited:
Mm, and then work around the fact that the current sim time is now lower than the time you went wheels up because the clock is starting again from zero, I follow. I think.
 
Don't worry, using MJD avoids any simt issues -- MJD always increases unless the user uses the scenario editor and resets the MJD to before the timer started -- but that's cheating. :)
 
Can't you just invoke oapi.get_simtime() and save the value when the engines start?

This part of the script does that, no?
Code:
-- wait for engines
while v:get_propellantmass (hp0) + v:get_propellantmass(hp1) == m1 do
    proc.skip()
end
t0 = oapi.get_simtime()


Then invoke oapi.get_simtime() later and get the delta (nowSimt - engineStartSimt).

Like this?
Code:
-- wait for docking event
mate = v:get_dockstatus (hd)
while mate==nil do
    proc.skip()
    mate = v:get_dockstatus (hd)
    if mate ~= nil then -- make sure we are docked to ISS
        v2 = vessel.get_interface(mate)
        if v2:get_name()~='ISS' then mate = nil end
    end
end
t1 = oapi.get_simtime() 

-- write out the results
dt = t1-t0
ptext = "Challenge completed successfully!\n"
ptext = ptext..string.format ("Mission Elapsed Time: %.2f seconds", dt)
note:set_pos (0.3,0.15,0.9,0.95)
note:set_size (1)
note:set_text (ptext)

This is what i've been doing so far, but i think there's something more i should add in the "wait for docking event" section, in order to get the MET displayed as soon as i ignite the engines. The syntax of it, still elludes me though...

Thank you for the quick replies. I should clarify that i started just yesterday reading the examples and tutorials of the Orbiter scripting user's guide.
 

Thanks Wishbone, the script you posted with your challenge is a great example, and answers various questions i had.

I have managed to get the mission time shown on screen as soon as the engines start and also show it as a result when my challenge's goals have been met.
Only thing is... it is in seconds. It's easy to convert it just to hours or just minutes, but how do i convert it to hours - min - seconds?
I think that i'd have to use some short of table to be able to do that.
Can anyone post an example?

Thank you in advance.
:cheers:
 
What about this (not tested :), and every time I use sprintf I look up man pages):
Code:
-- output : string
-- params: mjd1, mjd2 double, MJD dates, mjd2>=mjd1
function format_deltaTime(mjd1, mjd2)
local dt = mjd2-mjd1
local hrs = math.floor(dt*24)
local dmins = dt-hrs
local mins = math.floor(dmins*60)
local seconds = (dmins-mins)*60
local s = string.format("%g:%g:%.2f", hrs, mins, seconds)
return s
end
 
Last edited:
That was very helpfull, but i'm not quite there yet...

At this screenshot the engines started the same time as the simulation.
Simtime.jpg


Since i'm using oapi.get_simtime() instead of oapi.get_mjd(), i used the example in this way:

Code:
-- wait for engines
while v:get_propellantmass (hp0) + v:get_propellantmass(hp1) == m1 do
    proc.skip()
end
t0 = oapi.get_simtime() 

-- wait for docking event
mate = v:get_dockstatus (hd)
while mate==nil do
  t1 = oapi.get_simtime() 
  dta = t1-t0
  hrs = math.floor(dta/3600)
  dmins = dta-hrs
  mins = math.floor(dta/60)
  seconds = (dmins-mins)
  note:set_text (string.format("MET: %g Hours: %g Minutes: %.1f Seconds", hrs, mins, seconds, dta))
  proc.skip()

As the pic shows, the seconds don't start counting back from 0 when 1 minute has passed and the same goes for the minutes (when 1 hour has passed).
It also seems like i'm "losing" 1 second for every minute that passed. (See pic, 7215 simtime, 7093.2 displayed.)
 
Last edited:
To answer the whole minutes hours seconds thing:

local todhour = math.floor(todtimesec / 3600)
local todmin = math.floor(todtimesec / 60 - todhour * 60)
local todsec = math.floor(todtimesec - todhour * 3600 - todmin * 60)

(todtimesec is the total time in seconds)

Seems to work ok. This is LUA you're working in? It's quite late here and I'm not quite alert enough to fully check!!

Took me a while to figure that one out, I had a little help from google...;)
 
The function I gave relies on getting days in. to get h:mm:ss from seconds:

h = [dt/3600]
mm = [(dt-h*3600)/60]
ss = (dt-h*3600-mm*60)

square bracks are shorthand for math.floor
 
To answer the whole minutes hours seconds thing:

local todhour = math.floor(todtimesec / 3600)
local todmin = math.floor(todtimesec / 60 - todhour * 60)
local todsec = math.floor(todtimesec - todhour * 3600 - todmin * 60)

(todtimesec is the total time in seconds)

Seems to work ok. This is LUA you're working in? It's quite late here and I'm not quite alert enough to fully check!!

Took me a while to figure that one out, I had a little help from google...;)

Thanks flyer!
Yes, it's a LUA script for an XR2 challenge. Nowhere near as complicated as Wishbone's.
Just wanted to be able to show the Mission elapsed time for my "XR2 Ravenstar fastest docking with ISS" challenge.

The function I gave relies on getting days in. to get h:mm:ss from seconds:

h = [dt/3600]
mm = [(dt-h*3600)/60]
ss = (dt-h*3600-mm*60)

square bracks are shorthand for math.floor

That worked like a charm! Thank you very much for your time and patience.

@Wishbone: If you need any help modeling SAMs and Bunkers (Control huts) for your challenge, i'd be more than happy to provide the meshes.
:cheers:
 
Thanks, will be v.much obliged, guess the quickest way will be using Lua to model the vessels :cheers: The whole thing is on the backburner though till mid-October due to RL etc. intervening
 
Back
Top