kent logo

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 cylons


Question 54 (2007):

Submission reference: IN1383

I often find that my silly Cylons seem to be facing in one direction but not necessarily always moving in that exact direction. This generally happens when I am near a wall. Is this a bug in the code or something I have somehow managed ... because I can't understand how I could have done this?

Answer 54:

I'm afraid it's probably your bug ... without seeing your code, I can't know for sure.

Keep nagging at it! With a rotational velocity of zero, Cylons move forward in a straight line – following their central (red) ray. With a fixed small rotational velocity, they will curve in a fixed radius arc. Those rotational velocities should never get large. The worksheet recomends values between -10 and +10. See Question 40 (2007) for problems associated with large rotational velocities (ANGLEs per cycle).

Keywords: cylons

Question 53 (2007):

Submission reference: IN1382

Hello, I am trying to re-implement my Cylons assignment to use processes for the rules (as most of it is done using functions), but I am having trouble with the RANGES data. I have tried to use a delta process to copy the data stream to two processes (a speed and direction process) ... but the second parallel output in the delta always outputs an empty array. Is there anyway of copying the RANGES stream or can this only be done with integer streams?

Answer 53:

Yes, there is a simple way. But RANGES is a MOBILE data type, which does not get taught till the next module (Co632).

If you want to do as you describe, you need to know two things:

Here is a delta process for channels carrying RANGES:

  PROC delta.ranges (CHAN RANGES in?, out.0!, out.1!)
      RANGES ranges:
        in ? ranges
          out.0 ! CLONE ranges
          out.1 ! CLONE ranges

We have to CLONE twice in the above for the PAR to be safe. If we wrote:

          out.0 ! CLONE ranges
          out.1 ! ranges

the second component of the PAR sends the mobile data in ranges away, leaving the variable ranges changed (actually undefined). So, what is being cloned on the first component would depend on whether that happens before or after the second component. This breaks the parallel usage rules of occam-pi (which are there to ensure the scheduling order within a PAR doesn't matter). [Unfortunately, the present occam-pi compiler allows the above – this will be fixed. Meanwhile, don't do it!]

Here is a neat way to program the delta with only a single CLONE per cycle:

  PROC delta.ranges (CHAN RANGES in?, out.0!, out.1!)
      RANGES a, b:
        in ? a
        b := CLONE a
          out.0 ! a
          out.1 ! b

See the scene process in cylons.occ for another example of cloning. The data type being cloned there is RASTER, a MOBILE 2-D array of INTs (each INT is a pixel colour). RASTER is defined in the rastergraphics.module, included at the start of the file.

Keywords: cylons

Question 52 (2007):

Submission reference: IN1381

What exactly are we supposed to put into the report? The assignment says that we should detail any other rules we have implemented. Is this all you want, or is their anything else that should be included in the report? If you only want rules then my report isn't going to be a very long document.

Answer 52:

The report need not be very long at all – the worksheet asks only for a short report. It should say what rules you have decided for brain.1 to implement, together with any other changes you may have made to the simulation as a whole (this latter being optional). If you have gone parallel inside brain.1, that network should be drawn. If you have added/removed processes from the rest of the system, you should say why and draw the new network.

This report could be done as part of the documentation comments within you source file – but you may find it easier in a word-processed document.

Otherwise, new code that you write must be properly commented – preferably using the formal occamDoc style used in the starter file. Any clever coding fragments (which may be single lines) must have that cleverness explained. Any key variables declared must have their purpose explained. Anything obscure (without clarifying documentation) will be penalised.

Your report, if separate from your source code file, must be submitted alongside your source code. If you cannot produce an electronic version (in some reasonbly common format) for a separate report, you may hand hard copy in to CAS Reception – but that must be done before they close at 4pm. You will also have to ask for, and complete, a cover sheet for this assessment (title: "A4 - Robotics").

Keywords: cylons

Question 51 (2007):

Submission reference: IN1378

My problem, Question 50 (2007), happened while my Cylon was still using the supplied compute.speed function. I wouldn't have thought anything I did with the angle would have let the Cylon move into a wall?

Answer 51:

But some things you can do with the angle will move a Cylon into a wall!

The compute.speed function returns a speed depending on the minimum range detected by the laser scanner. Suppose a Cylon has its back to a wall. Its laser scans empty space – so its brain decides on a big forward velocity. Suppose its brain also decides on a big rotational velocity – say 120 degrees. That gets transmitted to its wheels (or whatever) along with the big forward velocity ... which results in the Cylon turning round and going splat, right into the wall, :(.

Cylons shouldn't rotate too fast, unless they are going forward very slowly or not at all. They don't know what's behind them!!

Keywords: cylons

Question 50 (2007):

Submission reference: IN1377

Occasionally, my Cylon changes from being all one colour to having a black and white spot in the middle. This will persist of 3 or 4 seconds. Why is this? Is this some aspect of the simulation I'm not aware of?

Answer 50:

Yep – the image rendering checks that a Cylon has not moved into a wall. See Pass 3 of the drone process. If a drone detects a hit, it allows it but renders that Cylon as you describe. So, if you see that happen, that's not good!

Each brain has its own drone, which represents the laser scanner and movement engine for the Cylon. The drone moves the Cylon (according to its current linear and angular velocities), renders it in the world images (rasters) flowing through, does its laser scan, reports the results to its brain, and receives new values computed by the brain for its velocities. For various logical reasons, the image rendering is done in three passes of the same image raster – this recycling is managed by the front and back processes (see the network diagram at the top of the file).

Of course, you don't need to know any of this to do the assignment!

Keywords: cylons

Referrers: Question 51 (2007)

Question 49 (2007):

Submission reference: IN1376

I am currently doing the Cylons assesment and I have encountered the CSUB0 error. Is there any place where I can find what that error means? Or can you explain me the cause of such error?

The error is in the function:

    ...  code omitted

Answer 49:

We're sorry about this low-level error message! It will be changed. CSUB0 is one of the BYTE-codes in the intermediate language generated by the occam-pi compiler and which the Transterpreter interptrets. It is the instruction generated to check that numbers (usually array indices) are within certain bounds. So, it almost always means an array bounds violation.

You pointed in your code snippet to the line on which the run-time system told you contained the error. That line has a reference to an array element. The index in that reference has gone out of bounds – your code has a bug.

As it says at the top of this page, this is not a forum for debugging your code. However ... you might check your min.index function, which return the minimum range and not the index of the minimum range. Also, in your left.to.center function (once you've fixed the above problem), the index will still go out of range if, for instance, your min.index parameter was equal to MID.RAY.

Keywords: cylons , stop , csub0

Question 47 (2007):

Submission reference: IN1375

I've just come to wrap up my cylons and am testing it on a different pc than the one on which I developed it. For some reason I'm getting a load of memory addresses spat out on the terminal and then this:

    exiting...(unimplemented instruction)
    The error occurred around like 91 in cordic.occ

I'm using the latest version of the transterpreter by the way ((20080116) transterpreter-2008.01.16)

Answer 47:

See the second bulleted item in the reports for Week 18 on the module webpage.

Keywords: cylons

Question 43 (2007):

Submission reference: IN1372

Hi, I'm changing the compute.speed function, but I had some trouble understanding the first one. Can you explain the code below because I can't find any explanations for the operators?

    IF i = 0 FOR 7
      range <= (robot.radius << i)
        speed := i


Answer 43:

The left and right shift operators, << and >>, are defined is slide 33 of basics and in section 2.2 ("Built-in Operators") of the occam-pi Quick Reference Wiki, which is linked from this module's web page.

See also Question 42 (2007), which observes that shifting the bit-pattern of a positive integer leftwards multiplies it by 2 for each bit shifted. So, expanding the above replicator fully (it's only 7 times) and replacing the shifts with equivalent multiplies, we get:

      range <= (robot.radius * 1)
        speed := 0
      range <= (robot.radius * 2)
        speed := 1
      range <= (robot.radius * 4)
        speed := 2
      range <= (robot.radius * 8)
        speed := 3
      range <= (robot.radius * 16)
        speed := 4
      range <= (robot.radius * 32)
        speed := 5
      range <= (robot.radius * 64)
        speed := 6

So long as range is not more than 64 times the radius of the robot, a speed will be assigned. In brain.0, that range is the minimum clear distance reported by the laser scanner. It sets the speed on a logarithmic scale, stopping it if it's bumped into something.

The greatest value the laser scanner can return is the length of its rays (see the variable laser.range in the main process). In that main process, laser.range is set to 32 times the robot.radius – so the above code is safe. If you change that ratio, you may need to protect that replicated IF – see Question 30 (2007).

Keywords: cylons , operators , shift

Question 42 (2007):

Submission reference: IN1369

What is the operator for raise-to-the-power? For example, 2^32 – what does occam-pi have for ^?

Answer 42:

occam-pi does not have a buiit-in raise-to-the-power operator. There is a built-in function for floating-point raise-to-the-power::


which returns x^y ... but I don't think you want that!

[By the way, the built-in adjective above just means that we don't have to import any module to use it – in the same way that java.lang classes don't need to be imported.]

The actual number 2^32 is, of course, too high to be represented by 32-bit integers. I'm a bit worried by various large numbers being mentioned (see also the 360 degrees, for angular velocities, in Question 40 (2007)). There is no need for large numbers in this exercise.

If we really need a power operator for integers, we can define our own:

    --* This computes a restricted integer power (not very efficiently).
    --  The power size must be positive.
    --  If the numbers are too large, there will be arithmetic overflow.
    -- @param x The number to be raised
    -- @param y The raising power (must be >= 0)
    -- @return [@ref x]^[@ref y]
      INT result:
          result := 1
	  SEQ i = 0 FOR y
            result := result*x
        RESULT result

To use this function, just use the specified symbol as an infix operator – for example:

    answer := n^i

This demonstrates two further mechanisms in occam-pi (that are not part of this course module): in-lining and user-defined operators.

The in-lining doesn't change any semantics – it just removes the function call overhead (inserting code for the body of the function wherever the call is made).

We can build new operators as single or double symbols, using any exisiting operator symbol (or ^, @, &, %, ...). As is normal, operator symbols can be overloaded – but each operator should be defined for a unique operand-type-result-type signature (otherwise, usual block-structure scope rules hide the previously defined operator for that signature). Operators are either infix binary or prefix unary (respectively two-parameter or one-parameter operator functions). If we put such things in some appropriate occam-pi module, the language acquires new operators. To this extent, occam-pi is user-extensible.

But this is an aside ... I still don't think you need a power operator. What you might need (and which the code already uses in compute.speed) is left-shift, <<, and right-shift, >>. So long as it doesn't overflow:

    n << i

shifts the bit pattern in n left by i bits. If n were positive, this multiplies it by 2^i (so long as there is no numeric overflow). Similarly:

    n >> i

shifts the bit pattern in n right by i bits. If n were positive, this divides it by 2^i (rounding towards zero). Maybe this is what you are after?

Keywords: cylons , operators , power

Referrers: Question 43 (2007)

Question 40 (2007):

Submission reference: IN1368

I added:

     initial.angular.velocity > (ANGLE.DEGREE*360)

to check the value being passed into the brain.1 method and the STOP condition is reached almost all the time. Does this mean the value being passed is not between 0 degrees and 360 degrees? If not, what is the value in relation to the 0-360 degree scale?

Also, am I right in saying that if the current angular.velocity (during the while-loop) is say, 270 degrees (270*ANGLE.DEGREE) then a move to the right would be something like angular.velocity PLUS (25*ANGLE.DEGREE)? Thanks.

Answer 40:

Good question – you have been experimenting!

The values of initial.angular.velocity are set randomly between -5 and +5 degrees (excluding zero) – see lines 534-536 in the place.robots procedure.

Recall: on the last page of the Cylons worksheet, the ANGLE datatype is described. Like TIMER values, they wrap around at 180 degrees, which is actually the same as -180 degrees. Comparisons between ANGLE values are therefore unsafe if the difference between them is more than (or equal to) 180 degrees – this is exactly the same as for time comparisons (which become unsafe beyond about 35 minutes – see "A Brief History of Time", slides 43-53 of basics).

So, if you had added checks like:

     initial.angular.velocity > (ANGLE.DEGREE*5)
     initial.angular.velocity < (ANGLE.DEGREE*(-5))

no STOP would have been executed.

Please don't have an angular.velocity (the amount of turn per cycle) of anything like 270 degrees – these are Cylons, not quasars! The worksheet suggests ranges between -10 and 10 degrees.

I don't understand the last part of your question. The angular.velocity is the amount of turn per cycle. The linear.velocity is the speed in the forward direction (along the central ray) on a scale of roughly pixels per cycle (but not quite, since the Cylon can be moving at any angle to the horizontal-vertical grid of pixels).

Keywords: cylons

Referrers: Question 42 (2007) , Question 54 (2007)

Question 39 (2007):

Submission reference: IN1365

I feel that the amount of coursework for this module is much more than any other module I've taken.

The assessments are getting much harder and overlapping two really doesn't help. Why couldn't the two final ones have been combined into one assessment testing both skills?

It might have been ok having two assessments from one module at the start of the term, but being a final year CS student, the deadlines regarding final year projects and other modules are building up.

Answer 39:

The final two assessments for this module are deliberately open-ended. We want to see what you can do – above a minimum requirement – and this gives you a chance to be creative. However, you will still get very good marks if you do the minimum.

The two assesments test different skills. The Cylons is about the logic for planning robot movement in response to a particular set of sensary data. It is embedded in a multi-robot graphics animation, the code for which is fun and effective but does not need to be understood or modified. The philosophers exercise is the opposite – we give you all the control logic and you are invited to construct a simple animation that shows what is happening. Testing both such skills at once would be daunting.

Each assessment has been given four weeks, with an overlap of two weeks when both can be being developed. You are not expected to work for four weeks on each of them! The long periods enable you to schedule the work in a way that works best for you.

Having said that, we do appreciate that final year students may have a special problem because their final year projects are due in week 23 (which is in the middle of the two deadlines for our final two assessments). So, for final year students, we will be relaxed about our deadlines. An announcement on this will shortly happen.

Keywords: cylons , q7

Referrers: Question 41 (2007)

Question 38 (2007):

Submission reference: IN1363

In the final hints for brain.1 you are saying that if the minimum is less than the robot radius, it's bumped - back off quick.

If the robot, ever comes to this situation then it is most propably, be in an overlapping mode. But since is not what we really want. This case is like a quard process which we never want to be exectuted.

Therefore is like a TRUE at the end of an IF. Am i missing something here?

Answer 38:

If the minimum range reported is less than the robot radius, it has bumped into something. In reality, that bump could be a disabling crash – so it's not something you should allow to happen. The Cylon should have slowed down and/or moved away so that it didn't happen.

Having said that, if it's only a little bump (i.e. the minimum range is only just less than the robot radius) and it bounces away quickly, we'll not mark that down.

I don't understand your reference to "a quard process which we never want to be exectuted" or "a TRUE at the end of an IF"? Your question describes a state that should not happen ... but I don't see that state in terms of an ALT guard or IF condition?

Keywords: cylons

Question 37 (2007):

Submission reference: IN1364

For assesment 4, I am interested in finding the angle between each ray. I have counted the rays and there are 35 rays. Therefore 34 angles? How can I get the total angle of the rays?

I will use the ray separation angle to implement the first part of the assesment. Am I taking the long way?

Answer 37:

You don't have to count the rays! Look at the constants defined at the start of the cylons.occ starter file (around line 56). The constant N.RAYS (which is commented: "number of rays") tells us the answer (33). The next constant is an angle, SCAN, set to 120 degrees and commented: "laser scan sweep". This is the total angle sweep of the arrays, so the angle between adjacent rays is:

    SCAN / (N.RAYS - 1)

Yes – it probably is useful to use this information.

Keywords: cylons

Question 36 (2007):

Submission reference: IN1361

For Assesment 4, does the RANGES array come in the order of:

Or is it the other way around?

Answer 36:

Humm ... looking at the fan procedure, which builds the ranges array, it moves psi (an ANGLE variable) from a small value (theta - phi) up by even increments (delta) through the straight-ahead (theta) and up to its final value (theta + phi). The angles psi moves through are the angles of the rays in the fan.

So. it depends on how the trig functions CORDIC (which converts from polar to cartesian coordinates) and CIDROC (which converts from cartesians to polars) treat polar angles. As they increase, is the point sweeping clockwise or anti-clockwise?

In (most) common views, increasing the angle means anti-clockwise. Think of the standard view of a 2D Euclidean plane, with X and Y axes crossing at (0, 0). From the origin, an angle of 0 (degrees) usually points to the right ... an angle of 45 (degrees) points top-right ... an angle of 90 (degrees) points straight up. So, increasing angles mean sweeping anti-clockwise.

If that is indeed how CORDIC is programmed (and the sources are available!), then the ranges array (which is built up in increasing order of angle) holds the distances of the rays going anti-clockwise – i.e. increasing array indices give ranges from the rightmost ray to the leftmost ray.

To find out for sure, add the mechanism for single stepping the Cylons simulation and printing our the ranges array each step (as discussed in your seminar groups). With only one brain.1 robot, it will quickly become apparent which way around the fan is represented by the ranges.

For the standard model of behaviour suggested for brain.1, we don't actually need to know the answer to your question! So long, that is, as the way angles are treated by the trig functions are the same as the way the motors treat the angular velocity component of its movement instructions. And they are so treated: increasing angles means anti-clockwise always ... or clockwise always. So long as there is this consistency, which way they go doesn't make any difference to the code that is needed for the necessary control.

Keywords: cylons

Question 33 (2007):

Submission reference: IN1351

I have a bit of a problem in terms of the random function. I've read through the answers on here already concerning this function, but when I use it ... it always seems to return the initial seed.

I have the following code to make the robot turn a random amount:

  INT number:
  VAL INT maxvalue IS 30:
  INITIAL INT seed IS 15:
        ...  code omitted
        number, seed := random (maxvalue, seed)
        ...  code omitted
      ...  whatever

I'm pretty sure it's always getting the same number. Have I used it in the correct way?

Answer 33:

If that really is an extract from your code, then no!

If the above is inside some loop, each time round the seed is re-declared and re-initialised to 15. So, that number is presented each time as the seed to the random function and each time it will compute the same results – not very random!

Your three declarations must be made just the once, before entering the loop:

  INT number:
  VAL INT maxvalue IS 30:
  INITIAL INT seed IS 15:
    ...  any other initialisation code
    WHILE still.running
        ...  stuff
              ...  code omitted
              number, seed := random (maxvalue, seed)
              ...  code omitted
            ...  whatever

Now, the first time around, random will be called with a seed value of 15. But it returns two values: one is the pseudo-random number computed and the other is an updated value for the seed. The next time around, random will be called with that updated seed ... and so on.

Note: please see Question 55 (2006) about warming up the random number generator (which is simple and effective, but you have to treat it right) first! See also this same question and Question 79 (2003) for clues about better ways to set the initial value for the random number seed.

Keywords: cylons , random

Question 32 (2007):

Submission reference: IN1355

In the last seminar, some of the groups apparently got a walkthrough of the cylons.occ code, with things like pointers on which bit to modify to achieve certain changes in behaviour and so on, a live demo of some code changes, and some discussion on possible approaches/end-results.

Is this material going to be replicated in the Cylons worksheet so that the group/s who didn't get this aren't unfairly disadvantaged?

Answer 32:

What happens in the seminar groups is largely driven by those attending. It is not possible to ensure that all groups experience the same things, nor is it desirable. However, we (the seminar leaders and myself) do plan the outline of work for the seminars so that there will be a common framework.

For assessment 4, there are no pointers necessary for which parts of the cylons.occ starter file to modify, other than those given in the worksheet for the assignment. All behaviour is governed by the logic you write for the brain.1 process – and nothing else!

You have been given logic for a brain.0 process as a crude example of what might be done. The live demo of some code changes shown in one of the seminars was a trivial variation of the live demo presented to all in the Friday lecture of Week 18. Nobody was disadvantaged (unless they missed that lecture).

For those who did miss that lecture, simply comment out the IF statement in the brain.0 process. Now you can do the demo yourself! You will see Cylons moving through walls and through each other - not good! There's nothing in the simulation code that enforces the solidity of walls or the robots. It's up to the Cylons themselves whether that happens. For the brains you program for this assessment, allowing such behaviour will lose marks.

You do not need to look at or understand or modify any other parts of the system defined in the cylons.occ starter file.

Unless you want to, of course! A good place to start would be to make sure you can follow the network diagram drawn near the start of the file with the parallel code in the top-level process. Specifying, making and documenting interesting changes in the rest of the system (e.g. being able interactively to turn off/on the display of the laser rays in the animation) would count towards the remaining 20% of marks for this assessment.

As described in the Cylons worksheet, implementing the functionality suggested for brain.1 in the worksheet (and demonstrated in the lectures) only earns 80%. Implementing and explaining additional, or radically different but still worthy, behaviour gets the rest. Making changes described in the previous paragraph is an alternative (or additional) way to earn that remaining 20%.

Keywords: cylons

Question 31 (2007):

Submission reference: IN1344

Can we write our own implementation of compute.speed method for brain.1? Because brain.1 has its different behaviour than brain.0.

Answer 31:

Yes, of course! But call it something different ... so that brain.0 will continue to function.

Keywords: cylons

Question 30 (2007):

Submission reference: IN1341

In the lectures, we were told that the IF statement requires a TRUE statement at the end. But in the compute.speed function of the assesment 4, there is not any TRUE statement:

  INT FUNCTION compute.speed (VAL INT range, robot.radius)
    INT speed:
      IF i = 0 FOR 7
        range <= (robot.radius << i)
	  speed := i
      RESULT speed

And still though we do not get a compiler error. How can this happen???

Answer 30:

Nope – you were not told that an IF statement requires a TRUE statement at the end! [To correct your terminology, there is no such thing as a TRUE statement ... you mean a TRUE condition. However, this is not your problem here.]

The semantics of an IF include the property: if all of its conditions evaluate to FALSE, it STOPs (which, in the default mode of compilation provided by the Transterpreter, provokes a run-time error). So, we only need a final TRUE condition if we have not dealt with all possible run-time conditions explicitly (earlier in the IF) and we need a none-of-the-above condition (triggering an appropriate action – which is often just SKIP).

The same is true for a replicated IF, such as appears in the compute.speed function (used by the brain.0 process in the cylons.occ starter file). No enclosing IF, nesting the replicated IF with a final TRUE conditional process, is mandated by the language – so there is no error for the compiler to report.

Therefore, the writer of this code is confident that at least one of the replicated IF conditions will always turn out to be TRUE. In fact, for the given parameters of the system (see the various VAL declarations early in the file), this will be true. However, if we vary things (e.g. reducing the robot.radius size, used in the replicated condition of this function and initialised in line 649), this replicated IF will indeed fail! Not good.

So, protect it – for example:

  INT FUNCTION compute.speed (VAL INT range, robot.radius)
    INT speed:
      VAL INT MAX.SPEED IS 7:    -- maybe this should be in the global list of VALs ...
        IF i = 0 FOR MAX.SPEED
          range <= (robot.radius << i)
            speed := i
	  speed := MAX.SPEED
      RESULT speed

Summary: Yes – the code is unsafe and the replicated IF should be protected (by nesting inside a simple IF with a TRUE condition). No – the code is perfectly legal as it is and the compiler is right to accept it.

Keywords: cylons

Referrers: Question 43 (2007)

Valid CSS!

Valid XHTML 1.0!

This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.
Last modified Mon May 20 13:50:26 2013
This document is maintained by Fred Barnes, to whom any comments and corrections should be addressed.