WAIT UP TO <milliseconds> in ABAP - abap

According to ABAP Documentation, the command WAIT UP TO x SECONDS needs an operand of type i. However, I'd like to WAIT UP TO x Milliseconds or something similar. Neither official documentation nor several other forum posts have been helpful thus far.
Is there any way to specify a wait for a fraction of a second?

You can simply pass a decimal value like:
WAIT UP TO '0.5' SECONDS
or something like:
WAIT UP TO '0.01' SECONDS
See also How to make an abap program pause.

If you want to avoid implicit commit with WAIT UP TO, create a simple RFC function:
FUNCTION ZSLEEP .
*"--------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*" IMPORTING
*" VALUE(DURATION) TYPE SDURATION_SECONDS
*"--------------------------------------------------------------------
* To wait 50 milliseconds write this:
* DATA duration TYPE sduration_seconds VALUE '0.050'.
* CALL FUNCTION 'ZSLEEP' DESTINATION 'NONE' KEEPING LOGICAL UNIT OF WORK EXPORTING duration = duration.
WAIT UP TO duration SECONDS.
ENDFUNCTION.

I've just solved it like this:
DATA: timestart TYPE timestampl,
timeend TYPE timestampl,
millisecs TYPE timestampl,
imilli TYPE i VALUE 200.
GET TIME STAMP FIELD timestart.
millisecs = imilli / 1000.
timestart = timestart + millisecs.
DO.
GET TIME STAMP FIELD timeend.
IF timestart < timeend.
EXIT.
ENDIF.
ENDDO.
WRITE timeend.
If I now rewrite this as a function taking an integer as an import parameter (in place of imilli) I'll - to my knowledge - have exactly what I wanted.
I'll leave this up for a little before tagging it as the correct answer in the hopes that someone may have a better / more elegant solution.

Without asking about the requirement, 2 ways to do this are
GET RUN TIME
where SET RUN TIME CLOCK RESOLUTION can be important.
or
GET TIME STAMP using a target field TIMESTAMPL
Do not use WAIT UP TO for fine time frames due to the Workprocess switching.
Wait also carries other side effects not immediately obvious.

Related

Create a variable to count from 1 to n in AnyLogic

I am looking to add a variable to count from 1 to 217 every hour in AnyLogic, in order to use as a choice condition to set a parameters row reference.
I am assuming I either need to use an event or a state chart however I am really struggling with the exact and cannot find anything online.
If you have any tips please let me know, any help would be appreciated
Thank you,
Tash
A state machine isn't necessary in this case as this can be achieve using a calculation or a timed event. AnyLogic has time() function which returns time since model start as a double in model time units of measurements.
For example: if model time units is seconds and it has been running for 2hr 2min 10sec then time(SECOND) will return 7330.0 (it is always a double value). 1/217th of an hour corresponds to about 3600/217 = 16.58 seconds. Also, java has a handy function Math.floor() which rounds down a double value, so Math.floor(8.37) = 8.0.
Assembling it all together:
// how many full hours have elapsed from the start of the model
double fullHrsFromStart = Math.floor(time(HOUR));
// how many seconds have elapsed in the current model hour
double secondsInCurrentHour = time(SECOND) - fullHrsFromStart * 3600.0;
// how many full 16.58 (1/217th of an hour) intervals have elapsed
int fullIntervals = (int)(secondsInCurrentHour / 16.58);
This can be packaged into a function and called any time and it is pretty fast.
Alternatively: an Event can be created which increments some count by 1 every 16.58 seconds and ten resets it back to 0 when the count reaches 217.

How to make an object appear after a specific amount of time in Processing

Im trying to make a program where you are a ship and you simply avoid comets that fly towards you. I somewhat know how to use array lists to add and subtract objects, but I'm not sure how to get the program to add and subtract objects after a specific time like 5 seconds. My goal is to make each comet spawn 2 seconds apart but I'm not sure how. If anyone can help please let me know!
Processing exposes a useful variable frameCount that you can use for such timing behaviours.
You could use it in combination with the modulo operator % (an operator that returns the remainder after the division of two numbers), as follows:
draw() {
.
.
.
if (frameCount % t == 0) {
spawnComet();
}
.
.
.
}
Assuming frameRate is fixed at 60, t takes the value of 60*(desired time delay in seconds). You want to spawn comets every 2 seconds: 60*2 = 120. Therefore set t to 120 to satisfy the requirement of your example. This means spawnComet() will trigger every 120 frames.

Elm - How to modify the parameterisation of one signal based on another signal

How can I parameterise one signal based on another signal?
e.g. Suppose I wanted to modify the fps based on the x-position of the mouse. The types are:
Mouse.x : Signal Int
fps : number -> Signal Time
How could I make Elm understand something along the lines of this pseudocode:
fps (Mouse.x) : Signal Time
Obviously, lift doesn't work in this case. I think the result would be Signal (Signal Time) (but I'm still quite new to Elm).
Thanks!
Preamble
fps Mouse.x
Results in a type-error that fps requires an Int, not a Signal Int.
lift fps Mouse.x : Signal (Signal Int)
You are correct there. As CheatX's answers mentions, you cannot using these "nested signals" in Elm.
Answer to your question
It seems like you're asking for something that doesn't exist yet in the Standard Libraries. If I understand your question correctly you would like a time (or fps) signal of which the timing can be changed dynamically. Something like:
dynamicFps : Signal Int -> Signal Time
Using the built-in functions like lift does not give you the ability to construct such a function yourself from a function of type Int -> Signal Time.
I think you have three options here:
Ask to have this function added to the Time library on the mailing-list. (The feature request instructions are a little bloated for a request of such a function so you can skip stuff that's not applicable)
Work around the problem, either from within Elm or in JavaScript, using Ports to connect to Elm.
Find a way to not need a dynamically changing Time signal.
I advise option 1. Option 3 is sad, you should be able to what you asked in Elm. Option 2 is perhaps not a good idea if you're new to Elm. Option 1 is not a lot of work, and the folks on the mailing-list don't bite ;)
To elaborate on option 2, should you want to go for that:
If you specify an outgoing port for Signal Int and an incoming port for Signal Time you can write your own dynamic time function in JavaScript. See http://elm-lang.org/learn/Ports.elm
If you want to do this from within Elm, it'll take an uglier hack:
dynamicFps frames =
let start = (0,0)
time = every millisecond -- this strains your program enormously
input = (,) <~ frames ~ time
step (frameTime,now) (oldDelta,old) =
let delta = now - old
in if (oldDelta,old) == (0,0)
then (frameTime,now) -- this is to skip the (0,0) start
else if delta * frameTime >= second
then (delta,now)
else (0,old)
in dropIf ((==) 0) 0 <| fst <~ foldp step start input
Basically, you remember an absolute timestamp, ask for the new time as fast as you can, and check if the time between the remembered time and now is big enough to fit the timeframe you want. If so you send out that time delta (fps gives time deltas) and remember now as the new timestamp. Because foldp sends out everything it is to remember, you get both the new delta and the new time. So using fst <~ you keep only the delta. But the input time is (likely) much faster than the timeframe you want so you also get a lot of (0,old) from foldp. That's why there is a dropIf ((==) 0).
Nested signals are explicitly forbidden by the Elm's type system [part 3.2 of this paper].
As far as I understand FRP, nested signals are only useful when some kind of flattering provided (monadic 'join' function for example). And that operation is hard to be implemented without keeping an entire signal history.

How can I (reasonably) precisely perform an action every N milliseconds?

I have a machine which uses an NTP client to sync up to internet time so it's system clock should be fairly accurate.
I've got an application which I'm developing which logs data in real time, processes it and then passes it on. What I'd like to do now is output that data every N milliseconds aligned with the system clock. So for example if I wanted to do 20ms intervals, my oututs ought to be something like this:
13:15:05:000
13:15:05:020
13:15:05:040
13:15:05:060
I've seen suggestions for using the stopwatch class, but that only measures time spans as opposed to looking for specific time stamps. The code to do this is running in it's own thread, so should be a problem if I need to do some relatively blocking calls.
Any suggestions on how to achieve this to a reasonable (close to or better than 1ms precision would be nice) would be very gratefully received.
Don't know how well it plays with C++/CLR but you probably want to look at multimedia timers,
Windows isn't really real-time but this is as close as it gets
You can get a pretty accurate time stamp out of timeGetTime() when you reduce the time period. You'll just need some work to get its return value converted to a clock time. This sample C# code shows the approach:
using System;
using System.Runtime.InteropServices;
class Program {
static void Main(string[] args) {
timeBeginPeriod(1);
uint tick0 = timeGetTime();
var startDate = DateTime.Now;
uint tick1 = tick0;
for (int ix = 0; ix < 20; ++ix) {
uint tick2 = 0;
do { // Burn 20 msec
tick2 = timeGetTime();
} while (tick2 - tick1 < 20);
var currDate = startDate.Add(new TimeSpan((tick2 - tick0) * 10000));
Console.WriteLine(currDate.ToString("HH:mm:ss:ffff"));
tick1 = tick2;
}
timeEndPeriod(1);
Console.ReadLine();
}
[DllImport("winmm.dll")]
private static extern int timeBeginPeriod(int period);
[DllImport("winmm.dll")]
private static extern int timeEndPeriod(int period);
[DllImport("winmm.dll")]
private static extern uint timeGetTime();
}
On second thought, this is just measurement. To get an action performed periodically, you'll have to use timeSetEvent(). As long as you use timeBeginPeriod(), you can get the callback period pretty close to 1 msec. One nicety is that it will automatically compensate when the previous callback was late for any reason.
Your best bet is using inline assembly and writing this chunk of code as a device driver.
That way:
You have control over instruction count
Your application will have execution priority
Ultimately you can't guarantee what you want because the operating system has to honour requests from other processes to run, meaning that something else can always be busy at exactly the moment that you want your process to be running. But you can improve matters using timeBeginPeriod to make it more likely that your process can be switched to in a timely manner, and perhaps being cunning with how you wait between iterations - eg. sleeping for most but not all of the time and then using a busy-loop for the remainder.
Try doing this in two threads. In one thread, use something like this to query a high-precision timer in a loop. When you detect a timestamp that aligns to (or is reasonably close to) a 20ms boundary, send a signal to your log output thread along with the timestamp to use. Your log output thread would simply wait for a signal, then grab the passed-in timestamp and output whatever is needed. Keeping the two in separate threads will make sure that your log output thread doesn't interfere with the timer (this is essentially emulating a hardware timer interrupt, which would be the way I would do it on an embedded platform).
CreateWaitableTimer/SetWaitableTimer and a high-priority thread should be accurate to about 1ms. I don't know why the millisecond field in your example output has four digits, the max value is 999 (since 1000 ms = 1 second).
Since as you said, this doesn't have to be perfect, there are some thing that can be done.
As far as I know, there doesn't exist a timer that syncs with a specific time. So you will have to compute your next time and schedule the timer for that specific time. If your timer only has delta support, then that is easily computed but adds more error since the you could easily be kicked off the CPU between the time you compute your delta and the time the timer is entered into the kernel.
As already pointed out, Windows is not a real time OS. So you must assume that even if you schedule a timer to got off at ":0010", your code might not even execute until well after that time (for example, ":0540"). As long as you properly handle those issues, things will be "ok".
20ms is approximately the length of a time slice on Windows. There is no way to hit 1ms kind of timings in windows reliably without some sort of RT add on like Intime. In windows proper I think your options are WaitForSingleObject, SleepEx, and a busy loop.

If passing a negative number to taskDelay function in vxworks, what happens?

Noted that the parameter of taskDelay is of type int, which means the number could be negative. Just wondering how the function is going to react when passing a negative number.
Most functions would validate the input, and just return early/return 0/set the parameter in question to a default value.
I presume there's no critical need to do this in production, and you probably have some code lying around that you could test with.... why not give it a go?
The documentation doesn't address it, and the only error codes they do define doesn't cover this case. The most correct answer therefore is that the results are undefined.
See the VxWorks / Tornado II FAQ for this gem, however:
taskDelay(-1) shows another bug in
the vxWorks timer/tick code. It has
the (side) effect of setting vxTicks
to zero. This corrupts the localtime
(and probably other things). In fact
taskDelay(x) will have the same effect
if vxTicks + x >= 0x100000000. If the
system clock rate is 100Hz this
happens after about 500 days (because
vxTicks wraps). At faster clock rates
it will happen sooner. Anyone trying
for several years uptime?
Oh there is an undocumented upper
limit on the clock rate. At rates
above 4294 select() will fail to
convert its 'usec' time into the
correct number of ticks. (From: David
Laight, dsl#tadpole.co.uk)
Assuming this bug is old, I would hope that it would either return an error or do the same thing as taskDelay(0), which puts your task at the end of the ready queue.
The task delay tick will be VIRTUALLY 10,9,..,1,0 for taskDelay(10).
The task delay tick will be VIRTUALLY -10,-11,...,-2147483648,2147483647,...,1,0 for taskDelay(-10).