CO538 Anonymous Questions and Answers Keyword Index |
This page provides a keyword index to questions and answers. Clicking on a keyword will take you to a page containing all questions and answers for that keyword, grouped by year.
To submit a question, use the anonymous questions page. You may find the keyword index and/or top-level index useful for locating past questions and answers.
Keyword reference for timers
2012 |
Submission reference: IN2294
I'm trying to do Task 3 of Life on Mars, but I'm having issues with the timeout - specifically, the actual time it waits is often absurdly long, sometimes minutes.
tim ? t PRI ALT tim ? AFTER t PLUS CAMERA.SCAN.TIME -- 2 seconds ... turn robot 90 degrees and increment a 'count' BLOB b: camera ? b ... if 'b' has the sought colour, set 'searching' FALSE & report to mission control
It doesn't matter whether there are any blobs in view or not, and recompiling or rerunning doesn't produce consistent results.
You don't show the enclosing loop. From what you show, I'm guessing something like:
WHILE searching AND (count < 4) SEQ tim ? t PRI ALT tim ? AFTER t PLUS CAMERA.SCAN.TIME -- 2 seconds ... turn robot 90 degrees and increment a 'count' BLOB b: camera ? b ... if 'b' has the sought colour, set 'searching' FALSE & report to mission control
Now, suppose a BLOB is reported on camera but not with the sought colour; then execution goes round the loop and the timeout is reset for another 2 seconds. The 'mandelbot' rock formations are reported (by the image processing processes running in parallel with your robot.control) as potential BLOBs down the camera channel, but will have different colours to the BLOBs sought by mission control. Further, so long as a potential blob is in view, it will continue to be reported down camera at least once every CAMERA.SCAN.TIME. In practice, CAMERA.SCAN.TIME is a bit generous and blobs may be reported a little more often than that.
So, if the sought BLOB is not in vision but something else is and that something gets sent down camera before your code times out, the potential blob is ignored and your timeout is reset for 2 more seconds. This can carry on indefinitely, the timeout never happens and your robot in never told to turn!
See "Choice" slide 46 for the right way to set the timeout times.
2011 |
Submission reference: IN2079
I get:
Error-occ21-q7.occ(40)- cannot open file "time.module"
I've looked in lib and sure enough it isn't there...
This looks like a response to the answer in Question 43 (2011). It looks like the search path set up for you on the Transterpreter doesn't reach all the libraries – which would be our fault.
However, that question was seeking a delay process and I'm assuming that that is what you are still seeking? The function of delay in the "time.module" is, as its documentation says, identical to the pause process given in your starter files for q1, q2, q3 and q4 (and e1). Just copy and use that – it's only these 7 lines of code:
PROC pause (VAL INT delay) TIMER tim: INT t: SEQ tim ? t tim ? AFTER t PLUS delay :
Submission reference: IN2077
I get:
Error-occ21-q7.occ(133)- delay is not declared
I looked at the occam documentation and it is there! What am I doing wrong?
Indeed it is: delay. However, if you scroll up from this documentation, you will see that it's in the module time. To use this, you will need the line:
#INCLUDE "time.module"
somewhere before you use delay in your code (next to the #INCLUDE line for "course.module").
We did not put the delay in the course module. It seemed too simple and you have been using it in many of your provious assignments (where its code was given in the starter files). We did not put it in the starter file for the Dining Philosophers' animation, since many solutions would use TIMERs directly.
POSTSCRIPT: apologies, I was confused by the incosistency in the names we chose! The starter files for q1..q4 have a delay process called pause. This has the same functionality as the delay process called delay in the "time.module".
Referrers: Question 46 (2011)
2010 |
Submission reference: IN1948
Is it possible to loop over some code for a specified duration? Something like:
SEQ tim ? t PRI ALT NOT (tim ? AFTER t PLUS 2000000) ... still waiting, do stuff SKIP SKIP
I've had a look over lecture slides and cannot find anything. I want to be certain I am receiving all the blobs from the camera before I start searching them for the correct colour.
Yes, but this is typically simpler than the code you have above. The "AFTER" operator can be used to test whether one time is after another, so can be used in conditionals. For example:
TIMER tim: INT start, stop: SEQ tim ? start stop := start PLUS 2000000 INITIAL BOOL waiting IS TRUE: WHILE waiting INT now: SEQ tim ? now IF stop AFTER now ... still waiting, do stuff TRUE waiting := FALSE
There are probably better (more elegant) ways to code this, but that should do what you want. If you really wanted to use an ALT with a timeout it could be coded something like:
TIMER tim: INT t: SEQ tim ? t INITIAL BOOL waiting IS TRUE: WHILE waiting PRI ALT tim ? AFTER (t PLUS 2000000) -- timeout reached waiting := FALSE SKIP ... still waiting, do stuff
However, this is polling a timer ...so probably isn't the best way to go about it. How about:
TIMER tim: INT t: SEQ tim ? t INITIAL BOOL waiting IS TRUE: WHILE waiting PRI ALT tim ? AFTER (t PLUS 2000000) -- timeout reached waiting := FALSE BLOB blob: camera ? blob ... check out this blob (if target, set waiting FALSE)
? That's much better, :). Now, it only does stuff if the camera sends a blob or the timeout happens – and this is the basic pattern for setting timeouts on waiting for things to happen!
You may need some more stuff in the above ... so that you can tell whether you exit the loop because you found the blob or timed out.
Keywords: timers , mars , polling
Referrers: Question 61 (2010)
2007 |
Submission reference: IN1453
Regarding time:
suppose t
is the current time, from a TIMER
,
and t1
is t
PLUS
100
.
For 100ms, (t
AFTER
t1
) will be
FALSE
.
As soon as the condition becomes TRUE
,
if I want to increase their difference again by 100,
am I going to add 101 or 100?
I know is a bit silly but I have been playing around with the maths and it seems logical to add 101 instead of 100.
occam-pi TIMER
s work to microseconds (us), not
milliseconds (ms). This is just to set your question in the right
units and does not otherwise affect the point you raise.
Suppose we have:
SEQ tim ? t tim ? AFTER t PLUS 0
where tim
is a TIMER
and t
is
an INT
.
The last line does not complete until the time on tim
is AFTER
what was recorded the line before.
Depending how far it was through the hardware timer's microsecond
when that time was recorded, the last line may have to wait:
if the timer has not moved on by (at least) one microsecond,
the last line will have to wait.
Suppose we have:
SEQ tim ? t tim ? AFTER t PLUS n
where n
is a non-negative INT
.
In this case, the last line will wait until the timer has moved on by
(at least) (n
+ 1) microseconds (from the time recorded
in the previous line).
[If n
were -1, the last line will not have to wait
(since the time on the timer will be AFTER
one
microsecond before the previous line executed).]
As you have observed, this is a little subtle (and that's bad!).
It would be more logical if occam-pi had an AFTER.OR.EQUAL
operator, that related to >=
in the same way as
AFTER
relates to >
.
Then, we could have:
SEQ tim ? t tim ? AFTER.OR.EQUAL t PLUS n
In which case, the last line would wait until the timer had moved
on by (at least) n
microseconds (from the time recorded
in the previous line).
But there is no AFTER.OR.EQUAL
operator!
For practical applications, however, this microsecond discrepancy
will not matter.
To set up a regular series of timeouts, evenly spaced every
n
microseconds, the correct template is:
TIMER tim: INT timeout: SEQ tim ? timeout timeout := timeout PLUS n WHILE <some condition> SEQ tim ? AFTER timeout timeout := timeout PLUS n -- set up next timeout value ... do some stuff
Notice that an actual time value is only recorded once
– before the loop is even entered.
Inside the loop, the values in timeout
advance
in exact increments of n
microseconds
– i.e. the timeouts in the series are always n
microseconds
apart from each other.
The result of having to write AFTER
,
rather than AFTER.OR.EQUAL
,
is that that series is always one microsecond after the series
we might have been expecting (because the initialisation of that
original timeout
value, before loop entry, was
one microsecond after what we might have thought).
Of course, if an incorrect template were used – such as:
TIMER tim: INT timeout: WHILE <some condition> SEQ tim ? timeout tim ? AFTER timeout PLUS n ... do some stuff
then timeouts of (n
+ 1) microseconds from the start
of each loop are being set.
The actual series of timeouts will be separated by (n
+ 1)
microseconds together with however long it takes to do the rest
of the stuff in the loop.
This will not be a regular series!
For information, here is a correct template for setting up a regular
series of timeouts (separated by n
microseconds) in
a process that also has to deal with other events:
TIMER tim: INT timeout: SEQ tim ? timeout timeout := timeout PLUS n WHILE <some condition> PRI ALT tim ? AFTER timeout SEQ timeout := timeout PLUS n -- set up next timeout value ... response to the timeout <another guard> ... response to this other guard <yet another guard> ... response to this other guard
where we have given the timeout highest priority (over the other events). Of course, some applications may need to give other events higher priority ... or even deal with them fairly (see Question 62 (2007)).
In all the above analysis, we are assuming perfect timers and that the process being considered is running on a sufficently fast processor (that can complete whatever else the process has to do before its next timeout is due). In practice, that won't always happen – especially when there are other processes sharing that same processor. Dealing with this takes us into the realm of hard and soft real-time systems, which was not included in this year's material (see Question 63 (2007)).
For interest however, you may note that, with the correct template, if a timeout is missed (because the process didn't get around to the timeout line in time), the timeout line will not delay anything – i.e. the response will be late ... but gets done as soon as possible. The next set timeout will still be for the original series schedule. So long as the processor can get through its response a bit quicker, the process will get back on schedule. This is what is needed for many soft real-time systems. At exceptionally busy times, some deadlines may be missed ... but it gets back on schedule as soon as the busy period ends. Note the emphasis on exceptionally.
Summary: the line:
tim ? AFTER timeout
does not terminate until the time value in the timer tim
is AFTER
the value of timeout
.
This means that it is guaranteed to wait until the time is (at least)
one microsecond after timeout
.
In practice, it may have to wait longer (for the run-time kernel to get
around to scheduling this process to run on some processor core).
If we wanted the guarantee to be for it to wait until the time is
(at least) timeout
, we should write:
tim ? AFTER (timeout MINUS 1)
Because the guarantees have that "(at least)" in them, there is
not much need for the above subtlety.
Guaranteeing to wait until (at least) one microsecond after
timeout
is also a guarantee to wait until (at least)
after timeout
.
Keywords: timers
Referrers: Question 72 (2007)
Submission reference: IN1429
Give examples of real-time systems that combine hard and soft real-time concepts and a brief description on the functionalities of one of the systems.
The course did cover issues dealing with time (e.g. TIMER
declarations, the occam-pi model of time, timeouts and timeout guards
in ALT
s). You need to be comfortable about programming
loops that have time-periodic cycles (e.g. a process that outputs once
per second how many inputs it received in the previous second).
However, this (2008) year we did not consider the common problems of real-time systems: how to calculate worst case response times, how to design systems so that such things can be calculated and minimised, and the concepts of hard and soft real-time. So, these things are not examinable.
For information, a hard real-time system is one whose specified deadlines must always be met – for example, collision detection systems in autonomous vehicles or the control avionics in a fly-by-wire airplane. If those deadlines get missed, the system crashes – literally!
A soft real-time system is one whose specified deadlines should be met most of the time – but only lead to temporary inconvenience when missed, with the system continuing to work and recovering to full functionality in time. Examples include: delivery of video data to a phone, processing bar-scanner readings at a supermarket checkout station, processing web forms for e-commerce.
An example of a system having elements of both: an avionics system combining the presentation of air-flow data to the head-up display for the pilot (soft) with the computation of wing surface movements, based on that air-flow data and other things, to keep the aircraft in stable flight (hard).
Keywords: timers
Referrers: Question 68 (2007)
2006 |
Submission reference: IN1094
In the class you wrote down an ALT
used for timing yet still taking in
data, but I didn't get the final version written down.
You made some adjustment that meant the timing period was only calculated once I think.
Could you give me the code again?
Thanks.
Hi – you need to be a bit quicker taking notes ... we did spend almost an hour on this!
All we were doing was waiting for either a channel input or
a timeout.
occam-pi has a particularly simple, efficient and elegant mechanism for
such things – the ALT
.
Here is the process we developed.
It's a clock process that ticks with a regular, but resettable,
period.
It doesn't do anything until a period is supplied (down its reset channel):
PROC clock (CHAN INT reset?, CHAN BOOL tick!) TIMER tim: INT timeout, period: SEQ reset ? period tim ? timeout timeout := timeout PLUS period WHILE TRUE PRI ALT reset ? period SKIP tim ? AFTER timeout SEQ tick ! TRUE timeout := timeout PLUS period :
Note the standard idiom when setting up a sequence of regular timeslices: check the actual time just the once ... then calculate the first time-out time before going into the loop. Inside the loop and when a timeslice ends, calculate the next timeout value from the last one – i.e. don't check the actual time again and calculate from that:
tim ? AFTER timeout SEQ tick ! TRUE tim ? timeout -- this is a mistake timeout := timeout PLUS period
because that means the timeslices will not have regualar periods. If the above were coded, the time betweem timeouts is period plus however long you have to wait for the tick to be taken plus however long it takes to check the time and calculate the next timeout.
With the original code above, the time betweem timeouts is period ... at least, the run-time system will do its best to make it so. If sometimes it takes more than period microseconds before the tick is taken, the next timeout will follow immediately. So long as that doesn't keep happening, the system will get back on schedule – the code is real-time stable.
There is an argument for checking the actual time again on receipt of a reset period. Suppose the current period were 10 seconds and we were 2 seconds into this when a reset arrives telling us to start ticking every second. The code given above would wait until the end of the currently defined period – i.e. another 8 seconds – before the next timeout occurs and, then, it starts ticking every second. [My windscreen wipers work like this when on intermittent sweeps: when I switch them to speed up, they wait until the end of (long) period before changing speed.]
Depending on the application, that may not be acceptable. If not, there is an easy solution:
PROC clock (CHAN INT reset?, CHAN BOOL tick!) TIMER tim: INT timeout, period: SEQ reset ? period tim ? timeout timeout := timeout PLUS period WHILE TRUE PRI ALT reset ? period SEQ tick ! TRUE -- immediately start a new sequence of ticks tim ? timeout timeout := timeout PLUS period tim ? AFTER timeout SEQ tick ! TRUE timeout := timeout PLUS period :
Now, if a reset to 1 second arrives 2 seconds into a 10 second period, it immediately starts ticking with the lower period (= faster rate). Whether that immediate tick in response to the reset should be done should be discussed with the engineer who is going to use this device. It's easily removed!
Keywords: timers
2004 |
Is this the correct piece of code for waiting a random time ?
SEQ seed := seed + id i, seed := random(num, seed) tim ? t tim ? AFTER t PLUS i
More or less, yes. Make sure you initialise "seed" appropriately though -- the code above initialises it based on itself (if undefined, it'll stay undefined). As covered in the seminars, a quick way to get an initial seed value is:
tim ? seed seed := (seed >> 2) + 1 -- maybe also add in the `id'
Remember also that your seed should be explicitly initialised like this just once -- before loop entry. Within the loop, cycling through the philosopher's life, the seed value gets updated as you use the random function. The sequence of seed values takes you through the "random" numbers. If you re-initialise the seed every time round the loop, the computed randomness will be lost.
Hi, what is the best way to to wait 1 second within a loop ? (Required for q5)
See the answer to Question 80 (2000).
Keywords: timers
2002 |
Could you please explain a little more how you would go about implementing the random time delay? I have read through the previous questions on it but I'm still a little lost. Is the time delay between philosophers doing different actions or in the display process?
It's in the philosopher processes - not the display.
The question says:
Thinking and eating by the philosophers should be modelled by random (but finite!) delays
In the "philosopher" process there are two folds:
<!--{{{ think--> SKIP <!--}}}-->
and:
<!--{{{ eat--> SKIP <!--}}}-->
You should replace the SKIPs by random delays.
Keywords: q7 , random , timers
2000 |
The question says:
"Thinking and eating by the philosphers should be modelled by random (but finite!) delays."
Assuming we have obtained a random number, what's the best way to implement the delay ... i.e. pause execution for a random time? Is there a wait(time) function or such like?
See slide 4-40 and sections 3.4/3.5 of the "OCCAM2 CHECKLIST" paper. Spelling it out:
TIMER tim: INT t: SEQ tim ? t tim ? AFTER t PLUS waiting.time
Referrers: Question 59 (2004)
When it comes to TIMERs, how is the time counted? Does the internal enviornment time in nanoseconds or microseconds? Also does it go like this:
1000000 nanoseconds = 1 second 10000 microseconds = 1 second
occam TIMERs, in KRoC Solaris/Linux systems, increment every microsecond. And, for information:
1000000000 nanoseconds = 1 second 1000000 microseconds = 1 second
Keywords: timers
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License. |